MySQL 8.0 生产环境执行在线 DDL 首选原生 ALGORITHM=INPLACE, LOCK=NONE 语法,大表或复杂变更建议配合 gh-ost 或 pt-online-schema-change 工具。核心风险在于元数据锁(MDL)阻塞业务查询以及磁盘空间不足导致操作失败。
先说结论:原生 Online DDL 适合多数结构变更,但需评估锁等待和空间,大表变更必须使用无锁工具。
- 先判断:确认变更类型是否支持 Instant DDL 或 Inplace 算法。
- 优先做:在从库或测试环境预演并备份全量数据。
- 再验证:检查
SHOW WARNINGS和业务延迟指标。
命令速用版
对于支持在线变更的操作,显式指定算法和锁策略可避免隐式拷贝表。
ALTER TABLE table_name ALGORITHM=INPLACE, LOCK=NONE;若需添加列且版本支持 Instant DDL,MySQL 会自动优化,但显式指定可确保预期行为。
为什么会这样
在线 DDL 的核心目标是减少表级锁持有时间,避免阻塞读写请求。MySQL 8.0 改用了更细粒度的元数据锁机制,但某些操作(如修改主键、更改字符集)仍可能触发表重建。若未指定 ALGORITHM,优化器可能根据情况选择 COPY 算法,导致长时间锁表。
分步处理
执行前需按顺序确认环境状态,操作中需监控进度,操作后需回滚准备。
步骤 1:数据备份
使用 mysqldump 或物理备份工具备份当前表结构及数据,确保可回滚。
步骤 2:检查支持情况
查询 information_schema.INNODB_METRICS 或在测试环境执行 EXPLAIN ALTER TABLE... 确认是否支持 INPLACE。
步骤 3:执行变更
在业务低峰期执行 DDL 语句,建议加上 LOCK=NONE 强制要求不锁表,若不支持则语句报错而非隐式锁表。
步骤 4:监控进度
查询 performance_schema.events_stages_current 查看执行阶段,避免进程卡死。
怎么验证是否生效
通过警告信息和性能状态确认 DDL 执行方式及影响。
检查警告:执行 SHOW WARNINGS; 查看是否有 Table does not support optimize/lock=none 等提示。
检查锁等待:查询 performance_schema.metadata_locks 确认是否存在长时间 MDL 等待。
检查业务影响:观察主从延迟秒数及应用端报错日志,确认无超时现象。
常见坑
- 元数据锁阻塞:长事务未提交会阻塞 DDL 开始,DDL 进行中会阻塞后续查询,需先 Kill 长事务。
- 磁盘空间不足:即使是 Inplace 算法,部分操作仍需临时空间,空间不足会导致操作失败甚至实例不可用。
- 外键约束:涉及外键的列变更通常不支持 Online DDL,需先删除外键再操作。
- 主键变更:修改主键通常触发表重建,无法做到完全在线,大表需使用工具。
常见问题
MySQL 8.0 所有 DDL 都是在线的吗?
不是,只有支持 ALGORITHM=INPLACE 的操作才是在线的,修改主键等操作仍会锁表。
大表加索引应该用什么工具?
建议使用 gh-ost 或 pt-online-schema-change,它们通过触发器或日志拷贝数据,避免锁表。
如何确认是否触发了 Instant DDL?
查看 information_schema.INNODB_METRICS 中相关计数器,或通过执行时间瞬间完成来判断。
参考来源
- MySQL Official Documentation, "Online DDL Operations", https://dev.mysql.com/doc/refman/8.0/en/online-ddl.html
- MySQL Official Documentation, "Instant ADD COLUMN", https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl.html