ruby-on-rails - 在 8000 万行表上索引 UUID

标签 ruby-on-rails ruby postgresql activerecord

我们使用 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/

相关文章:

ruby-on-rails - 您应该如何在 Rails 中回填新表?

sql - Postgres 在 DELETE 时降低触发器性能

macos - 为什么 Postgres.app 不启动 psql

ruby-on-rails - 如何在 RSpec 中使用 Spree 路由助手

css - 在 Rails 中使用 Less 文件

ruby - Nokogiri(在 Ubuntu 上)的可靠安装过程是什么?

ruby - 正则表达式 - 分隔符之间的所有子字符串

ruby - 如何通过 Ruby 更改进程的优先级

ruby-on-rails - 我的Rails路由与pushState Ember.js路由一起使用应该看起来像什么?

ruby-on-rails - 是否有可能在rails中获取访问者的mac地址?