无需停机即可更改大表

cra*_*ike 9 mysql alter-table mysql-5.6 percona-toolkit

我有一个非常大的表,让我们调用它example,然后我尝试在该表上执行一些更改命令:

ALTER TABLE `example` ADD `example_column` TINYINT(1) NOT NULL DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)

检查alter命令的进度:

mysql -e 'show engine innodb status \G' | grep 'undo \| log \| entries'
Run Code Online (Sandbox Code Playgroud)

给我很好的信息,关于时间 - 或多或少需要 17 天才能完成......

更改阻塞表,因此阻塞生产表 17 天不是一个好的选择。;)

我尝试在网上调查一些很棒的工具,例如:

  1. pt-online-schema-change - Percona
  2. gh-ost - GitHub 的 MySQL 在线架构迁移

我还阅读了文档和上述工具的限制部分:

鬼魂限制

  • 根本不支持触发器
  • 根本不支持外键

pt-online-schema-change 限制

  • 触发器的使用意味着如果表上已经定义了任何触发器,则该工具将无法工作。

  • 不提供任何改变包含外键的表的好方法

我的示例表有触发器和外键...

你能给我一些建议,如何处理这个改变?

我有 MySQL 5.6。我使用 GTID(基于行)复制。

我将非常感谢您的建议!

Rol*_*DBA 5

你最好像这样运行 ALTER TABLE

ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;
Run Code Online (Sandbox Code Playgroud)

有什么好处?定义默认值为 的列NULL不会尝试增加行的大小。对于VARCHAR. 老实说,我不确定这对数字是否正确。(INT、TINYINT 等)。您需要对此进行测试(我在 2 年前提到过对此进行测试(InnoDB 是否允许将列添加到具有并发 READ/WRITE 行的表?))。因此,不应有停机时间。

这样做的缺点是更改您的软件以处理NULL数字列。

如果您担心外键,请事先在会话中将其关闭

SET foreign_key_checks = 0;
ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;
Run Code Online (Sandbox Code Playgroud)

如果您有触发器并且可以在加载期间没有它,请放下触发器,执行ALTER TABLE,然后重新创建触发器。

警告:确保您使用的是最新版本的 MySQL 5.6(至少 5.6.23)以避免ALTER TABLE.

请注意,我没有提到使用第三方工具。这只是直接的 MySQL。

试一试 !!!