是否可以 运行 优化 TABLE 而无需复制 lag/downtime?

Is it possible to run OPTIMIZE TABLE without having replication lag/downtime?

我有一个 table 有 100,000,000 条记录和 500GB 的数据。我一直在将许多旧记录备份到备份数据库中,然后从主数据库中删除它们。但是磁盘 space 并没有减少,我注意到 data_free 对于 table 已经增长了很多。

我的理解是我需要 运行 OPTIMIZE TABLE 来减小磁盘大小,但是我读到这会导致复制延迟。我正在使用 mysql 5.7 InnoDB。

所以我的问题是,我可以 运行 OPTIMIZE TABLE 而不会导致复制滞后吗?例如 运行ning OPTIMIZE TABLE on master 如:

OPTIMIZE NO_WRITE_TO_BINLOG TABLE tblname;

然后运行在奴隶上一个一个地执行同样的命令。那行得通吗?这样做有什么风险吗?或者还有其他方法吗?

在我的公司,我们使用 Percona 的免费工具 pt-online-schema-change

它实际上并没有执行优化 TABLE,但是对于 InnoDB tables,任何 table-copy 操作都将实现相同的结果。也就是说,它创建一个新的 InnoDB table 空间,将所有行复制到该 table 空间,并重建该 table 的所有索引。新的 tablespace 将是原始 tablespace 的碎片整理版本。

任何更改都可以,您无需更改 table 中的任何内容。我使用空操作 ALTER TABLE <name> FORCE.

pt-online-schema-change 的优点是在工作的同时,你可以继续读写 table。它只需要一个简短的元数据锁来在开始时创建触发器,最后需要另一个简短的元数据锁来交换新的 table 和旧的。

如果您使用 OPTIMIZE TABLE,这会导致较长的复制滞后,因为它不会在副本上启动 运行,直到它在源上完成。

而对于 pt-online-schema-change,它会立即启动 运行 table-copy,并与其他并发事务一起继续,当它在源上完成时,它是等一下它也在副本上完成。

它实际上比 OPTIMIZE TABLE 花费的时间更长,但由于它不会阻止您使用 table,所以这无关紧要。

我最终通过设置复制环境在本地进行了测试。

似乎可以 运行 OPTIMIZE TABLE tblname; 而不会导致任何停机或复制滞后。

您需要在主服务器上 运行 OPTIMIZE NO_WRITE_TO_BINLOG TABLE tblname;,以避免写入 bin 日志并将查询复制到从服务器。

然后你必须运行OPTIMIZE TABLE tblname;在每个奴隶中单独

这里有更详细的解释:https://dev.mysql.com/doc/refman/5.7/en/optimize-table.html#optimize-table-innodb-details

它说:

an exclusive table lock is only taken briefly during the prepare phase and the commit phase of the operation.

所以几乎没有锁定时间

有一些边缘情况需要担心会导致停机(由于 table 在线 DDL 上的复制方法导致锁定),其中一些在上面的 link 中列出。

另一件需要考虑的事情是磁盘space。使用 InnoDB,我观察到它重新创建了 table。因此,如果您 table 的内容加起来达到 100GB,则您至少需要额外的 100GB 免费 space 才能成功 运行 命令。

正如 Bill 所建议的那样,使用 pt-online-schema-change 可能是一种更安全的替代方法,但是如果您不能使用它,小心操作似乎不会出现复制延迟,也不会出现停机时间。