我们正在使用带有postgres的Ruby on Rails迁移,将索引添加到具有8000万行的表上的UUID类型列。
我们遵循concurrently
模式和disable_ddl_transaction!
。但是,在部署之后不久,在迁移期间,我们开始注意到严重的减速并最终表停止响应。我们在中途取消了迁移,表终于恢复了,但是我们仍然不知道是什么导致表停止响应。
我们正在使用AWS RDS,我们检查了所有统计数据,看起来我们的CPU或I / O都没有达到最大值。
我的问题是,在迁移过程中可能会导致我们减速/停机的其他因素是什么?
其他表正在响应,应用程序正在加载,但这一张表只是卡住了。
这是迁移:
class AddIndexToPublicId < ActiveRecord::Migration
disable_ddl_transaction!
def up
change_column :table1, :public_id, :uuid, null: false
change_column :table2, :public_id, :uuid, null: false
change_column :table3, :public_id, :uuid, null: false
add_index :table1, :public_id, unique: true, algorithm: :concurrently
add_index :table2, :public_id, unique: true, algorithm: :concurrently
add_index :table3, :public_id, unique: true, algorithm: :concurrently
end
def down
remove_index :table1, :public_id
remove_index :table2, :public_id
remove_index :table3, :public_id
change_column :table1, :public_id, :uuid, null: true
change_column :table2, :public_id, :uuid, null: true
change_column :table3, :public_id, :uuid, null: true
end
end
迁移的change_column
部分似乎工作正常,但索引没有完成,所以我们现在处于一个奇怪的状态,我们的schema.rb与我们的数据库不匹配。
答案 0 :(得分:2)
我认为它会减慢因为您一次添加许多并发索引。根据{{3}}
使用此选项时,PostgreSQL必须对表执行两次扫描,此外,它必须等待可能修改或使用索引终止的所有现有事务。
因此,当添加并发索引时, Postgres必须执行两次表扫描。
尝试分解您的迁移:
change_column
的一次迁移。add_index
的一次迁移。一次只运行一个。