必须先定位持锁者再精准终止:kill query仅中断语句并立即释放mdl锁,kill connection则强制回滚,可能因回滚过程持续持有exclusive锁而加剧阻塞;查不到锁需确认performance_schema已启用且wait/lock/metadata/sql/mdl采集器开启。

直接杀错线程会让锁卡得更久,必须先定位持锁者再精准终止——KILL QUERY和KILL CONNECTION行为完全不同,选错等于雪上加霜。
查不到持锁线程?先确认performance_schema是否真在干活
很多环境里performance_schema默认开启但关键采集器被关着,查metadata_locks表永远为空。不是没锁,是根本没记。
-
SELECT @@performance_schema;必须返回1,否则整个机制不启动 - 执行
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME = 'wait/lock/metadata/sql/mdl';,这是MDL锁的“开关” - 执行
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'global_instrumentation' OR NAME LIKE 'thread_instrumentation';,否则线程信息不会入库 - 注意:这些配置只对新建立的连接生效,已存在的连接不会补录历史锁状态
Waiting for table metadata lock时,到底该KILL QUERY还是KILL CONNECTION?
看锁持有者的事务状态——它是不是还在跑、有没有改数据、有没有提交。
- 如果持锁者是长
SELECT或空闲连接(Command = 'Sleep'且Time > 60),用KILL CONNECTION,因为锁绑在连接生命周期上,语句早结束了但连接还挂着 - 如果持锁者正在执行大事务(比如
UPDATE改了几十万行但还没提交),优先用KILL QUERY:它只中断当前语句,事务仍存在但MDL锁立即释放;而KILL CONNECTION会触发回滚,回滚过程本身持续持有MDL_EXCLUSIVE锁,阻塞时间可能翻倍 - DDL被卡住时,
sys.schema_table_lock_waits视图里BLOCKING_TRX_ID对应的线程,就是你要处理的目标——别靠SHOW PROCESSLIST猜
ALGORITHM=INSTANT能绕过MDL锁吗?
不能。INSTANT只跳过数据拷贝,不跳过元数据锁。
-
ALTER TABLE ... ALGORITHM=INSTANT仍需获取MDL_EXCLUSIVE锁,照样会被未提交的SELECT或UPDATE阻塞 - INSTANT仅支持极窄操作:添加非首列、重命名列、改默认值;加索引、删列、改类型、删主键等一律退化为
COPY或INPLACE,锁行为不变 - 哪怕语法支持INSTANT,只要表上有活跃事务(哪怕只是
START TRANSACTION; SELECT * FROM t;),DDL依然卡在Waiting for table metadata lock
最危险的盲区是:以为INNODB_TRX里没事务就安全了。MDL锁由Server层管理,跟InnoDB事务完全无关——一个自动提交模式下的SELECT执行完就释放连接,但若客户端没断开,它仍可能以Sleep状态持锁数小时。排查必须从performance_schema.threads和metadata_locks出发,而不是只盯INNODB_TRX。











