instant加列无需元数据锁,因其仅修改数据字典系统表(如mysql.columns)中的列定义,不触碰用户数据页或索引结构,server层原子提交即可完成;但执行前仍需短暂获取mdl_shared_read锁校验表状态,遇长事务、mdl_shared_write锁或并发ddl时会阻塞。

INSTANT加列为什么不需要元数据锁?
因为ALGORITHM=INSTANT不修改任何用户数据页,也不重排行结构,只在数据字典系统表(如mysql.columns、innodb_sys_columns)里插入一条新列定义记录——这个操作本身由Server层原子提交,且全程不触碰InnoDB的聚簇索引或二级索引B+树,自然无需申请表级排他MDL锁。
它不是“绕过”锁,而是根本没到需要锁的阶段:传统COPY/INPLACE要读写数据页、重建索引、刷redo log,必须持锁防止并发DML破坏一致性;INSTANT连磁盘数据都不看一眼,只改几条系统表记录,事务提交即完成,DML照常执行。
哪些场景下INSTANT仍会卡住?
INSTANT本身不争MDL,但执行前仍需获取一次轻量级的元数据读锁(MDL_SHARED_READ),用于校验表状态。以下情况会导致阻塞:
-
SELECT ... FOR UPDATE或INSERT ... SELECT等语句正持有该表的MDL_SHARED_WRITE锁 - 长事务未提交,其持有的
MDL_SHARED锁未释放(查information_schema.INNODB_TRX确认TRX_STARTED时间) - 表上存在正在执行的其他DDL(哪怕只是
ALTER TABLE ... COMMENT='xxx'),也会排队等待
注意:ALGORITHM=INSTANT失败时抛出ERROR 1845 (0A000),不会静默降级;而ALGORITHM=DEFAULT可能 fallback 到INPLACE,那才真要抢MDL。
验证INSTANT是否真正生效的关键指标
不能只看语句返回快,得确认它确实走了INSTANT路径:
- 执行
SHOW CREATE TABLE t1,确认引擎是InnoDB,且无FULLTEXT索引 - 查
SELECT ROW_FORMAT, KEY_BLOCK_SIZE FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = 'db/t1',确保ROW_FORMAT不是COMPRESSED,且KEY_BLOCK_SIZE = 0 - 检查是否显式主键缺失:若表无
PRIMARY KEY且无NOT NULL UNIQUE列,则MySQL 8.0.12–8.0.27不支持INSTANT - 成功后查
INFORMATION_SCHEMA.INNODB_TABLES里的INSTANT_COLS字段,非0表示已启用instant元信息区
INSTANT的“零锁”是严格限定条件下的结果,漏掉任意一个硬性约束,就退回INPLACE甚至COPY——这时候锁和耗时全回来了。











