INSTANT DDL不需长时间持锁,因其仅修改mysql.columns等系统表记录,不触碰用户数据页、索引或行结构,Server层原子提交即完成;但执行前仍需短暂获取MDL_SHARED_READ锁校验表状态。

INSTANT DDL 不需要长时间持锁,是因为它根本没动数据页——只改了几条系统表记录,事务一提交就完事。
INSTANT 为什么连数据页都不碰
MySQL 8.0 把表结构(列名、类型、默认值、顺序)全存进 mysql.columns 这类 InnoDB 系统表里,不再依赖磁盘 .frm 文件。INSTANT 操作(比如 ADD COLUMN)只是往 mysql.columns 插一条新行,同时更新 innodb_sys_columns;InnoDB 层完全不读写任何用户数据页、不重排行结构、不重建索引、不刷 redo log。
这意味着:没有物理数据变更,就没有一致性保护的强需求,自然不需要长时持有 MDL 排他锁(MDL_EXCLUSIVE)或阻塞 DML。
-
ALGORITHM=INSTANT失败时会直接报错ERROR 1845 (0A000),不会静默降级 - 成功后查
INFORMATION_SCHEMA.INNODB_TABLES的INSTANT_COLS字段,值非 0 才算真正生效 - 老数据行读取时,由 Server 层按当前字典定义动态补默认值或
NULL,不是提前填充
INSTANT 仍要抢的那两次轻量锁在哪
虽然不碰数据,但 MySQL 仍需短暂获取 MDL_SHARED_READ 锁,用于校验表状态是否允许变更。这两次锁发生在:准备阶段(检查元数据可写性)和提交阶段(原子更新系统表)。每次持续通常不到 10ms,但以下情况会让它卡住:
- 有长事务未提交,其持有的
MDL_SHARED锁未释放(查information_schema.INNODB_TRX中的TRX_STARTED) - 其他会话正执行
SELECT ... FOR UPDATE或INSERT ... SELECT,持有MDL_SHARED_WRITE锁 - 表上已有其他 DDL 正在排队(哪怕只是
ALTER TABLE ... COMMENT)
哪些操作看似简单却立刻退出 INSTANT
INSTANT 支持范围极窄,稍越界就 fallback 到 INPLACE(甚至 COPY),锁时陡增。典型踩坑点:
-
ADD COLUMN c INT NULL DEFAULT 0→ INSTANT OK;但紧接着MODIFY COLUMN c INT NOT NULL DEFAULT 0→ 必退INPLACE - 加列时用
AFTER col_x或FIRST指定位置 → 不支持 INSTANT(MySQL 8.0.29+ 才支持) - 表无显式主键,且无
NOT NULL UNIQUE列 → MySQL 8.0.12–8.0.27 直接拒绝 INSTANT - 行格式为
COMPRESSED或KEY_BLOCK_SIZE > 0→ INSTANT 不可用
INSTANT 的“零锁”是严格条件下的结果:漏掉任意一个硬性约束(比如默认值类型变更、字段顺序调整、压缩行格式),它就退回 INPLACE——这时候锁和耗时全回来了。


















