在线DDL优化需避开锁表高峰、控制粒度、用MySQL 5.6+ ALGORITHM=INPLACE/LOCK=NONE、影子表迁移、精准控锁,并协同低峰期、灰度与回滚策略。

在线DDL(Data Definition Language)操作在高并发业务场景中极易引发锁表、主从延迟甚至服务中断。核心优化思路是:避开锁表高峰、控制变更粒度、利用数据库原生在线能力、配合业务低峰期与灰度策略。
利用MySQL 5.6+原生ALGORITHM=INPLACE
MySQL 5.6起支持多数ALTER语句的in-place执行,不重建表、不阻塞DML(如INSERT/UPDATE/DELETE)。关键在于显式指定算法和锁级别:
- ALGORITHM=INPLACE:优先走行级拷贝或元数据变更,避免全表复制
- LOCK=NONE:完全无锁(适用于添加列、修改列默认值、增删二级索引等)
- LOCK=SHARED:允许读、禁止写(如修改列类型但不涉及数据重排)
执行前用EXPLAIN FORMAT=JSON ALTER ...或查看INFORMATION_SCHEMA.INNODB_TRX确认是否真正走in-place路径;避免隐式降级为COPY算法(如给大表加主键、修改TEXT字段长度)。
拆分大变更:分阶段+影子表迁移
对无法in-place的变更(如修改主键、调整分区、大字段类型变更),采用“影子表+增量同步”方式:
- 新建影子表(
_new后缀),执行目标结构变更 - 用工具(如pt-online-schema-change、gh-ost)双写主表与影子表,实时同步增量
- 校验数据一致性后,原子性切换表名(RENAME TABLE)
该方案全程不锁原表,但需额外磁盘空间与监控binlog延迟;建议提前压测同步吞吐,避免追平时间过长。
精准控制锁范围与时长
即使使用in-place,某些操作仍会短暂持有MDL(Metadata Lock)或行锁。优化要点:
- 避免在事务中执行DDL:DDL本身会隐式提交,且MDL会阻塞后续查询
- 禁用自动提交时慎用ALTER:确保连接未处于长事务中(查
INFORMATION_SCHEMA.PROCESSLIST) - 对超大表,用
pt-online-schema-change --chunk-size限制单次处理行数,降低锁等待概率
可结合SELECT * FROM performance_schema.metadata_locks实时观察锁持有者与等待链。
配套运维与业务协同策略
技术方案需匹配运维节奏与业务容忍度:
- 严格安排在业务低峰期(如凌晨2–4点),并设置超时中断(
pt-osc --max-lag) - 发布前冻结相关表的写入逻辑(如临时下线写接口、切到只读模式)
- 灰度上线:先在小库/测试环境验证,再按分片或租户逐步推进
- 预留回滚方案:影子表保留72小时,原表结构快照存档
不复杂但容易忽略。










