在线 DDL(Online Data Definition Language)是 MySQL(尤其是 InnoDB 存储引擎)从 5.6 版本开始引入的重要特性,用于在执行表结构变更(如新增索引、添加字段等)时,尽可能减少对表的锁定时间,允许业务读写操作在大多数阶段正常进行。
在线 DDL 的核心特点:
-
低锁表时间:
- 仅在操作开始和结束时持有短暂的元数据锁(MDL),中间过程不阻塞读写。
- 避免了传统 DDL 操作(如 MyISAM 的全表锁)导致的长时间业务中断。
-
支持的主要操作(以 InnoDB 5.7 为例):
- 新增二级索引(最常用场景)。
- 添加/删除列(部分场景,如添加非空默认值列可能有特殊处理)。
- 修改列的数据类型(有限支持,可能需要表重建)。
- 重命名表、添加主键(需谨慎,可能涉及表重建)。
-
实现原理:
- 先创建一个临时表,记录原始表的结构变更逻辑。
- 后台异步复制原始表数据到临时表,并维护一个日志记录变更期间的新增写操作。
- 完成数据复制后,应用日志中的增量变更,最后切换表名并释放锁。
-
注意事项:
- 资源消耗:执行期间会占用额外的 CPU、IO 和磁盘空间,可能影响数据库性能。
- 长事务影响:若有未提交的长事务持有 MDL 读锁,在线 DDL 会等待锁释放,可能变相导致“锁表”。
- 并非所有操作都“完全在线”:如修改主键、删除列等操作可能仍需短暂锁表或重建表。
- 大表风险:对超大表执行在线 DDL 仍可能耗时较长,建议在低峰期操作,并提前备份。
如何使用在线 DDL?
无需特殊语法,正常执行 ALTER TABLE
即可触发,例如:
-- 为 users 表的 email 字段添加二级索引(在线操作)
ALTER TABLE users ADD INDEX idx_email (email);
替代方案(针对超大型表):
如果在线 DDL 仍可能影响业务,可考虑:
- 使用
pt-online-schema-change
(Percona Toolkit 工具),通过创建影子表和触发器实现无锁变更。 - 手动建新表迁移数据,通过 rename 切换表名(适合停机窗口允许的场景)。
总之,在线 DDL 大幅提升了 MySQL 表结构变更的灵活性,但需根据具体操作类型和数据量评估风险,避免在高并发时段执行。