用途:给亿级表加列、加索引、改类型而不锁业务
| 算法 |
是否阻塞 DML |
说明 |
COPY |
是 |
全表复制到新表,锁写,旧版本方式 |
INPLACE |
多数不阻塞 |
在引擎内构建新结构(加索引、部分列变更) |
INSTANT |
否 |
仅改元数据(8.0 加列到末尾、改默认值等),秒级完成 |
语法:ALTER TABLE t ADD COLUMN c INT, ALGORITHM=INSTANT; 明确指定算法可让不满足条件的变更直接报错,而不是悄悄退化成锁表。
- 元数据锁 MDL:变更需要拿到排他 MDL;若有长查询或未提交事务持读锁,DDL 排队并阻塞后续所有新查询(雪崩式)。
- 临时空间与日志:加索引需要排序与大量 redo,可能撑爆磁盘并放大复制延迟。
- 表重建:改主键、改字符集、改列类型需要重建整表。
| 手段 |
说明 |
低峰执行 + lock_wait_timeout 小值 |
拿不到 MDL 就快速失败,不拖垮业务 |
| 先杀长事务 |
变更前后检查 information_schema.innodb_trx |
| 在线改表工具 |
gh-ost(binlog 驱动,无触发器)、pt-online-schema-change(触发器 + 影子表):复制数据→追增量→原子改名 |
| 分批 DDL |
分区表可按分区做;大索引创建可拆多列 |
| 从库先行 |
在从库执行再切换(部分工具支持),避免主库阻塞 |
| 回滚预案 |
影子表保留期与改名回退步骤 |
- 加列优先于改列:新增列 + 双写 + 回填 + 切读,比原地改类型安全得多。
- 字符集/排序规则变更是重建级操作,必须专项评估(含索引长度与唯一性语义变化)。
- 索引变更注意唯一索引冲突会导致失败;先清理脏数据。
- 变更脚本必须幂等,失败可重跑;所有 DDL 进版本库与评审。
| 误区 |
修正 |
| 以为 8.0 有 INSTANT 就都秒完成 |
只有特定操作是 INSTANT,改类型仍重建 |
| 高峰期“就加个索引” |
加索引会重建二级结构并产生大量 IO 与 redo |
| DDL 卡住就 kill 连接 |
回滚可能比执行更久,需评估 |
| 不做从库延迟观察 |
大 DDL 常导致分钟级延迟,影响读流量 |
依赖 ALGORITHM 默认行为 |
显式指定,让不满足条件的语句失败而不是锁表 |
- MySQL 官方文档:Online DDL、innodb_online_alter_log_max_size
- GitHub gh-ost、Percona pt-online-schema-change 文档