查INNODB_TRX可快速定位事务锁等待根源:TRX_STATE='LOCK WAIT'为等待方,TRX_STATE='RUNNING'且TRX_STARTED过早者多为持锁元凶;结合SHOW PROCESSLIST和INNODB_LOCK_WAITS可明确等待链;MDL锁需通过performance_schema排查。

查 INNODB_TRX 找出“赖着不走”的事务
锁等待的根源几乎总是某个没提交、卡住或执行太久的事务。直接查 information_schema.INNODB_TRX 是最快路径,它反映当前所有活跃事务的真实状态。
-
TRX_STATE = 'LOCK WAIT'表示该事务正在等锁,是“受害者”,不是元凶 -
TRX_STATE = 'RUNNING'且TRX_STARTED时间很早(比如几分钟前),大概率是元凶——它持着锁没放 -
TRX_MYSQL_THREAD_ID是关键字段,后续要靠它关联到具体连接 -
TRX_QUERY可能为空:事务只执行了BEGIN、SQL 已跑完但事务未结束、或用了预处理(如 PDO emulate mode)
用 SHOW PROCESSLIST 定位对应连接和 SQL
拿到 TRX_MYSQL_THREAD_ID 后,立刻执行 SHOW PROCESSLIST,找匹配的 ID 行。这才是你真正能操作的入口。
-
Command = 'Sleep'且Time很大 → 应用拿了连接没关,事务可能还挂着 -
State = 'Updating'或'Locked'且Time持续增长 → SQL 卡在 I/O 或锁本身 -
Info字段显示的是最后执行语句,但可能被截断;为空也不代表没在跑 SQL - 注意:
KILL的是ID,不是TRX_ID;优先用KILL QUERY ID,避免中断整个连接
看 INNODB_LOCK_WAITS 理清“谁在等谁”
单个事务看不出锁链全貌。INNODB_LOCK_WAITS 是唯一能直接看到等待关系的视图,字段名自带因果逻辑:
-
waiting_trx_id和blocking_trx_id明确标出等待方与持有方 -
blocking_pid对应SHOW PROCESSLIST中的ID,可直接 kill -
waiting_query是卡住的语句,blocking_query经常为NULL——因为持有锁的事务可能已执行完 SQL,只是事务没提交 - 若
blocking_trx_started比当前时间早很多,基本可锁定为长事务未提交
别漏掉 Metadata Lock(MDL)这种“隐形杀手”
DDL 操作(如 ALTER TABLE)被卡住,或者普通 SELECT 突然集体阻塞,大概率是 MDL 锁问题。它不会出现在 SHOW PROCESSLIST 的 State 里,得查 performance_schema:
- 确保
performance_schema = ON,且events_waits_current和threadsconsumers 已启用 - 执行:
SELECT THREAD_ID FROM performance_schema.events_waits_current WHERE EVENT_NAME = 'wait/lock/metadata/sql/mdl' AND STATE = 'WAITING' - 再用该
THREAD_ID关联performance_schema.threads查PROCESSLIST_INFO - 典型元凶:未提交的事务里执行过
SELECT,接着有人想ALTER同一张表;或FLUSH TABLES WITH READ LOCK没释放
真正难定位的从来不是锁本身,而是那个开着事务却不提交、连自己都忘了的连接。查 INNODB_TRX 时多盯两眼 TRX_STARTED 时间戳,比反复看 SQL 更有效。


















