MySQL 8.0Notes

第 25 章:DDL 与原子性

zjc 于 2026-01-25 发布

这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 MySQL 8.0 的数据字典支持原子 DDL,使元数据变更要么提交要么回滚。执行层面仍要区分 INSTANT、INPLACE 和 COPY,以及锁和并发 DML。

25.1 原子 DDL

prepare dictionary
  -> storage engine prepare
     -> commit dictionary
        -> post DDL

原子性解决:

  1. .frm 与引擎元数据不一致;
  2. DDL 中断后字典残留;
  3. 部分提交状态;
  4. 重复重试困难。

25.2 算法

算法 特点
INSTANT 修改元数据
INPLACE 引擎内变更
COPY 重建并复制数据

指定方式:

ALTER TABLE t ADD COLUMN c INT, ALGORITHM=INSTANT;
ALTER TABLE t ADD INDEX idx_c(c), ALGORITHM=INPLACE;

如果操作不支持指定算法,DDL 会失败而不是降级。

25.3 并发 DML

ALTER TABLE t ADD INDEX idx_c(c), ALGORITHM=INPLACE, LOCK=NONE;

锁模式:

模式 含义
NONE 允许并发 DML
SHARED 允许读、阻塞写
EXCLUSIVE 阻塞读写

即使 LOCK=NONE,DDL 仍需要短暂元数据锁,长事务会阻塞它。

25.4 Online DDL 阶段

MDL exclusive probe
  -> prepare
     -> build
        |-- concurrent DML log
        +-- read data
           -> apply row log
              -> commit
                 -> final MDL

大表 Online DDL 仍可能占用:

  1. 临时磁盘;
  2. row log;
  3. redo;
  4. CPU 和 IO;
  5. 长时间 MDL 窗口。

25.5 常见操作

操作 常见方式
加列 8.0 多数可 INSTANT,受位置和版本限制
删列 通常 INPLACE 或 COPY
加索引 INPLACE
删索引 INPLACE
修改列类型 常 COPY
更改主键 重建
字符集转换 可能 COPY

必须按当前小版本验证。

25.6 第三方在线 DDL

gh-ost 和 pt-online-schema-change 通过影子表和增量同步减少锁影响。

选择:

工具 思路
gh-ost binlog 异步复制到影子表
pt-osc 触发器同步

使用前要评估磁盘、binlog、延迟、触发器兼容性和切换窗口。

25.7 生产流程

评估算法和锁
  -> 测试库演练
     -> 测量耗时和空间
        -> 检查长事务
           -> 低峰执行
              -> 监控 MDL/IO/延迟
                 -> 验证结构和数据

本章小结

原子 DDL 保证数据字典一致性,执行代价仍由算法和锁决定。生产 DDL 要先确认当前版本支持情况,评估空间和锁窗口,并在低峰执行或使用在线工具。

思考题

  1. 原子 DDL 是否等于不锁表?
  2. INSTANT、INPLACE、COPY 的差异是什么?
  3. 为什么 LOCK=NONE 仍可能等待 MDL?
  4. Online DDL 的 row log 有什么代价?
  5. 什么时候选择 gh-ost 或 pt-osc?