MySQL 在线模式迁移的现状
引言
如何在 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 模式变更在技术上是非阻塞的,但它有不少限制:
- 主库表现提交查询的服务器(通常是主库)上,DML 查询(如
SELECT
,INSERT
,UPDATE
,DELETE
等)是非阻塞的,可以正常执行。然而,其他 DDL 查询会被阻塞,这是预期行为。 - 资源密集型操作MySQL 服务器会尽可能多地使用 CPU 和磁盘 I/O 来完成模式变更。这种资源消耗会对繁忙的服务器性能产生影响。
- 额外磁盘空间要求需要额外的磁盘空间,最大可以达到原始表的大小。
- 无法中断你只能通过强制终止查询来中止操作。这会导致大规模的后续清理操作,进一步消耗磁盘 I/O。
- 副本库阻塞在副本服务器上,操作是阻塞的。比如如果在主库上
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 COLUMN
和 DROP COLUMN
的支持。
INSTANT 模式变更真正实现了瞬时操作:
- 无需复制表数据;
- 不需要额外磁盘空间;
- 无需占用大量 CPU;
- 操作完成几乎在一瞬间,甚至在副本上也是瞬时完成。
这听起来完美!而在其支持场景下,它确实非常理想,尽管还有些细微限制。查看官方文档时可以发现,受支持变更类型如下:
- 更改列的默认值;
- 增加/删除虚拟列;
- 修改
enum
定义; - 其他。
这些变更的共同点是,它们都属于元数据修改。它们不会影响现有行数据,不会修改表数据结构,不会影响索引。而 ADD COLUMN
和 DROP COLUMN
是唯一会影响表数据和数据结构的更改。
以下变更不受支持:
- 更改列的数据类型;
- 增加具有非字面值默认值的列;
- 增加索引;
- 修改主键定义;
- 增加/删除外键;
- 更改表的字符集;
- 分区变更。
INSTANT 风险
尽管 INSTANT DDL 通常风险较低,但它仍存在一些隐患:
- 破坏性操作:比如
DROP COLUMN
会导致数据丢失。 - 查询中断:删除列可能会破坏原有的 SQL 查询。
解决方案:外部工具
多种第三方工具已出现,用于运行 MySQL 在线模式变更。其中包括 Vitess(PlanetScale 背后的技术支持)、gh-ost、pt-online-schema-change、spirit 等。
这些工具通常采用类似的基本设计,并具有以下特点:
- 模拟
ALTER TABLE
,通过创建一个影子表逐步复制数据以实现新模式; - 完成时间可能比 MySQL 原生方法更长;
- 需要额外磁盘空间;
- 会导致二进制日志膨胀;
- 遵守生产负载,必要时暂停或节流;
- 操作支持中断,可随时取消;
- 能够处理几乎所有类型的模式变更。
Vitess 和 spirit 更进一步,支持自动检测迁移是否可以通过 INSTANT DDL 执行,从而简化决策过程。此外,Vitess 原生支持**可逆性(revertibility)**,不仅能还原模式,还能保留因变更可能丢失的数据,同时确保所有新增、更新和移除的数据被正确记录。
第三方解决方案总结
对于大多数使用场景,第三方在线模式变更工具仍是当前和未来的首选解决方案。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接