引言

如何在 MySQL 中运行非阻塞的模式变更?这是一个经久不衰的问题。随着越来越多的第三方解决方案的出现以及 MySQL 的最新进展,选择哪种方案来处理给定的模式迁移变得愈加复杂。在本文中,我们对 2024 年 MySQL 在线模式迁移的现状进行高级别概述。我们将讨论范围限定为 ALTER TABLE 语句,因为其他 DDL(数据定义语言)语句通常执行速度较快(DROP TABLE 是一个例外,但超出了本文讨论范围)。
首先,我们将探讨 MySQL 的原生选项:**INPLACE** 和 **INSTANT**。参考MySQL 8.0 官方文档以了解在线 DDL 操作的支持情况。


INPLACE,也叫 InnoDB 在线 DDL

这是 MySQL 对非阻塞模式变更的最早尝试。一些类型的 ALTER TABLE 语句(具体支持列表请参考链接)可以通过 ALGORITHM=INPLACE 来运行。尽管 INPLACE 模式变更在技术上是非阻塞的,但它有不少限制:

  1. 主库表现提交查询的服务器(通常是主库)上,DML 查询(如 SELECT, INSERT, UPDATE, DELETE 等)是非阻塞的,可以正常执行。然而,其他 DDL 查询会被阻塞,这是预期行为。
  2. 资源密集型操作MySQL 服务器会尽可能多地使用 CPU 和磁盘 I/O 来完成模式变更。这种资源消耗会对繁忙的服务器性能产生影响。
  3. 额外磁盘空间要求需要额外的磁盘空间,最大可以达到原始表的大小。
  4. 无法中断你只能通过强制终止查询来中止操作。这会导致大规模的后续清理操作,进一步消耗磁盘 I/O。
  5. 副本库阻塞在副本服务器上,操作是阻塞的。比如如果在主库上 ALTER TABLE 操作耗时 3 小时,那么从主库完成后可以预计副本会暂停复制大约 3 小时,由此产生大量的复制延迟。

副本问题是大多数场景中的致命缺点。解决方法之一是在主库上运行 ALTER TABLE 时关闭二进制日志(SQL_LOG_BIN=0),使其不会复制到副本。然后逐个副本单独运行相同的操作。这种技术可行,但会导致不一致问题。例如如下场景:你是否跟踪了所有服务器?如果后来从备份恢复或引导(bootstrap)一个副本,该副本可能没有应用过该变更,该如何解决?此外,这种技术需要更长的时间完成,因为你需要逐个服务器运行变更操作。尽管部分操作可以进行并行化,但并不总能完全并行化。

INPLACE 总结

综合以上原因,**INPLACE** 并不是非阻塞模式变更的良好选项。


INSTANT 模式变更

INSTANT 模式变更几乎是数据库领域的圣杯。它支持某些类型的模式变更通过 ALGORITHM=INSTANT 运行。最早由腾讯六年前贡献给 MySQL,INSTANT DDL 最初只支持一种类型的变更:ADD COLUMN。后来,MySQL 增加了对更多类型变更的支持,比如扩展 enum 列定义,或增加和删除虚拟列。一年前,MySQL 8.0.29 添加了对任意 ADD COLUMNDROP COLUMN 的支持。
INSTANT 模式变更真正实现了瞬时操作:

  • 无需复制表数据;
  • 不需要额外磁盘空间;
  • 无需占用大量 CPU;
  • 操作完成几乎在一瞬间,甚至在副本上也是瞬时完成。

这听起来完美!而在其支持场景下,它确实非常理想,尽管还有些细微限制。查看官方文档时可以发现,受支持变更类型如下:

  • 更改列的默认值;
  • 增加/删除虚拟列;
  • 修改 enum 定义;
  • 其他。

这些变更的共同点是,它们都属于元数据修改。它们不会影响现有行数据,不会修改表数据结构,不会影响索引。而 ADD COLUMNDROP COLUMN 是唯一会影响表数据和数据结构的更改。
以下变更不受支持:

  • 更改列的数据类型;
  • 增加具有非字面值默认值的列;
  • 增加索引;
  • 修改主键定义;
  • 增加/删除外键;
  • 更改表的字符集;
  • 分区变更。

INSTANT 风险

尽管 INSTANT DDL 通常风险较低,但它仍存在一些隐患:

  1. 破坏性操作:比如 DROP COLUMN 会导致数据丢失。
  2. 查询中断:删除列可能会破坏原有的 SQL 查询。

解决方案:外部工具

多种第三方工具已出现,用于运行 MySQL 在线模式变更。其中包括 Vitess(PlanetScale 背后的技术支持)、gh-ost、pt-online-schema-change、spirit 等。
这些工具通常采用类似的基本设计,并具有以下特点:

  • 模拟 ALTER TABLE,通过创建一个影子表逐步复制数据以实现新模式;
  • 完成时间可能比 MySQL 原生方法更长;
  • 需要额外磁盘空间;
  • 会导致二进制日志膨胀;
  • 遵守生产负载,必要时暂停或节流;
  • 操作支持中断,可随时取消;
  • 能够处理几乎所有类型的模式变更。

Vitess 和 spirit 更进一步,支持自动检测迁移是否可以通过 INSTANT DDL 执行,从而简化决策过程。此外,Vitess 原生支持**可逆性(revertibility)**,不仅能还原模式,还能保留因变更可能丢失的数据,同时确保所有新增、更新和移除的数据被正确记录。


第三方解决方案总结

对于大多数使用场景,第三方在线模式变更工具仍是当前和未来的首选解决方案。



MySQL 在线模式迁移的现状插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.choupangxia.com/2025/09/14/mysql-online-state/