MySQL MDL锁阻塞DDL 导致复制线程卡住
一、MDL锁基础概念
MDL锁是MySQL中的元数据锁,用于保护数据库对象的元数据,确保在并发环境下数据库对象结构的一致性。(MDL锁的适用对象包括表,存储过程,函数,触发器和表空间等)
二、MDL锁监控配置
-- 验证监控状态
SELECT * FROM performance_schema.setup_instruments WHERE name LIKE '%mdl%';-- 启用MDL监控
UPDATE performance_schema.setup_instruments 
SET enabled = 'yes' 
WHERE name = 'wait/lock/metadata/sql/mdl';

三. 生产场景
主从同步,备库数据同步 一直卡在一个时间点不动。
检查 show processlist 输出

观察到 状态:Waiting for table metadata lock, 加字段,从库有事务占用mdl锁。
分析事务阻塞信息

有两个事务从8月6日开始,已经运行多日未提交这些事务持有MDL读锁,阻塞了DDL操作需要的MDL写锁
长时间运行事务(trx_id: xxx) ↓ 持有 MDL READ LOCK
DDL操作(添加字段) ↓ 等待 MDL WRITE LOCK (Waiting for table metadata lock)↓
从库复制线程↓ 等待 DDL 完成
数据同步卡住
kill掉大事务后数据同步恢复。
mysqldump --single-transaction 是否会产生MDL锁?
会,产生 MDL 共享读锁,按表逐个加锁,但每个表的锁定时间很短,阻塞DDL。

select 语句是否会产生大量MDL锁?
SELECT 语句本身通常不会产生大量 MDL 锁,但在以下特定场景下会成为 MDL 锁问题的根源:
- 长事务中的 SELECT:在未提交的事务中,SELECT 会持有 MDL SHARED_READ 锁直到事务提交 
- 长时间运行的复杂查询:大数据量查询、复杂关联查询等执行时间过长,在整个执行期间持有 MDL 锁 
- 高并发 SELECT:大量并发查询虽然单个锁时间短,但可能形成锁等待链 
这些场景会阻塞需要 MDL EXCLUSIVE 锁的 DDL 操作,在主从复制环境中,从库的 DDL 被阻塞会导致复制线程卡住,造成复制延迟。
