【问题标题】:create an index without locking the DB创建索引而不锁定数据库
【发布时间】:2011-03-09 05:45:52
【问题描述】:

我有一个包含 10+ 百万行的表。我需要在单个列上创建索引,但是,创建索引需要很长时间,以至于我会锁定表。

需要注意的是,索引是作为“rake db:migrate”步骤的一部分创建的……如果可以的话,我不反对手动创建索引。

更新:我想我应该提到这是一个经常写入的表。

【问题讨论】:

  • 锁没问题。您是否遇到超时或死锁?
  • 锁不好。这就是抱怨。
  • 你找到答案了吗?
  • @Richard,如果您将 MySQL 更新到 >5.1.7 版本,看起来您可以创建一个不锁定数据库的索引。我还没有尝试过,我很幸运能够安排一个较短的停机时间窗口(在安装期间),我可以在其中应用索引。
  • 如果您使用 MySQL,请尝试 facebook OSC 或 Percona Toolkit。我们对用于在线模式更改的 Percona 工具包非常满意。

标签: mysql rake ruby-on-rails


【解决方案1】:

MySQL NDBCLUSTER 引擎可以在线创建索引而不锁定对表的写入。但是,使用最广泛的 InnoDB 引擎不支持此功能。另一个免费的开源数据库 Postgres 支持“同时创建索引”。

【讨论】:

  • 'create index concurrently' 是在 8.2 或更高版本中添加的。
  • 最近我们一直在使用 Percona 工具包进行在线模式更改,而无需使用 InnoDB 锁定表。
【解决方案2】:

你可以用这样的东西(伪代码)来防止阻塞:

create table temp like my_table;
update logger to log in temp;
alter table my_table add index new_index;
insert into my_table select * from temp;
update logger to log in my_table;
drop table temp

记录器是在常规使用中向您的表添加行/更新的地方(例如:php 脚本)。这将设置一个临时表,以便在另一个更新时使用。

【讨论】:

  • 我想我应该提到这是一个经常写的表。因此,临时表将很难实现,但并非不可能实现。只是有点不理想。
【解决方案3】:

尝试确保在插入记录之前创建索引。这样,索引也将在填充表的过程中被填充。虽然这需要更长的时间,但至少在 rake 任务完成后它就可以开始了。

【讨论】:

  • 大部分索引都是这样创建的;然而;与普遍的看法相反,Oracle 和 Microsoft 的向导不断地告诉他们的 DBA 在性能开始滞后时重建他们的索引。此外,在某些 ETL 案例中,稍后进行索引实际上更有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 2021-02-23
  • 2012-07-28
  • 2020-03-22
  • 2012-10-06
  • 1970-01-01
  • 2017-04-30
相关资源
最近更新 更多