我们使用 Ruby on Rails 迁移和 postgres,将索引添加到具有 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 与我们的数据库不匹配。
最佳答案
我认为它变慢了,因为您一次添加了许多并发索引。根据Postgres document
When this option is used, PostgreSQL must perform two scans of the table, and in addition it must wait for all existing transactions that could potentially modify or use the index to terminate.
因此当添加并发索引时,Postgres 必须执行两次表扫描。
尝试分解你的迁移:
change_column
的一次迁移。- 为每个
add_index
进行一次迁移。
并且一次只运行一个。
关于ruby-on-rails - 在 8000 万行表上索引 UUID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47067605/