MDL 堵表应急:先 KILL 那条 ALTER
找到了元凶 A(不提交的事务)和 B(排在队头的 ALTER),先杀谁?
先杀 B。 队头的写锁请求一没,排队的查询立刻拿到读锁(和 A 的读锁兼容),马上止血。我试的时候,KILL B 之后被堵的查询一秒内就返回了。
杀 A 也能解堵,但会回滚别人的业务事务,而且 B 拿到写锁后还会继续跑一会儿。先止血,再回头查 A 为什么不提交。
下次改表前做两件事:
-- 1. 看有没有长事务
SELECT * FROM information_schema.innodb_trx;
-- 2. 在同一个会话里给 ALTER 设个等锁上限
SET SESSION lock_wait_timeout = 5;
ALTER TABLE cfg ADD COLUMN remark VARCHAR(64);lock_wait_timeout 管的是等 MDL,默认 31536000 秒,也就是一年,所以 ALTER 能一直等下去。设成几秒之后,拿不到锁就报 1205 放弃,过会儿重试,不会一直堵着后面的查询。
别和 innodb_lock_wait_timeout 搞混:那个管等行锁,默认 50 秒。