在不停机的情况下向生产 MySQL 数据库添加索引?

Den*_*ard 2 mysql index migration high-availability

我希望通过添加适当的索引来提高在生产中运行的大型 MySQL 数据库的查询性能。我们尝试在实时数据库上添加索引,但这当然会锁定数据库并使我们的应用程序不可用。

我们曾考虑使用更新的索引创建辅助数据库,然后迁移数据库数据。这将涉及一些停机时间。

有没有更好的方法来做到这一点?那不涉及停机时间吗?

预先感谢您的帮助

Rol*_*DBA 5

如果要向活动表添加索引,有两种主要方法:

方法 #1:pt-online-schema-change(首选)

这个工具很壮观。它将为您创建一个临时表并填充它。

简单来说,它为 mydb.mytable 执行此操作:

CREATE TABLE mydb.mytable_new LIKE mydb.mytable;
INSERT INTO mydb.mytable_new SELECT * FROM mydb.mytable;
RENAME mydb.mytable TO mydb.mytable_old,mydb.mytable_new TO mydb.mytable;
DROP TABLE mydb.mytable_old;
Run Code Online (Sandbox Code Playgroud)

然而,pt-online-schema-change远不止于此。

如果已复制到临时表的行被更新或删除怎么办?好吧, pt-online-schema-change将触发器添加到源表来为您处理那些插入后的更改。当复制到临时表完成时,触发器会在切换之前移除。

如果实时系统具有高负载或服务器,还有一些选项可以限制(例如--max-load--critical-load)或停止(例如--pause-file)到临时表的副本具有落后于特定秒数的从站(例如--max-lag)。

您还可以选择仅测试语法 ( --dry-run ) 或实际运行更改 ( --execute )。

有一些选项可以将 sql_log_bin 等变量设置为 0 并检查外键约束。

这个工具的局限性?

  1. 确保在切换发生之前有足够的空间放置临时表。例如,如果源表是 200G,我会确保磁盘上至少有 250G 可用空间。
  2. 以秒为单位的瞬时中断以切换临时表和旧表。

方法 #2:在线 DDL

MySQL 还能够使用本机 SQL 在线执行 DDL。

看我以前的帖子

不幸的是,在线 DDL 没有限制或停止操作的选项。

结语

这些天我使用pt-online-schema-change因为我可以控制这个过程需要多快或多慢。我什至可以在一天内停止并恢复它。有一次,我和另外两个 DBA对一个 30GB 的读写超高的数据库执行了pt-online-schema-change。与我们合作的开发团队要求我们在白天暂停复制到临时表,并在夜间恢复复制。我们在三天内完成了这项工作。一切都很成功,应用程序从未受到影响。