最直接入口是查information_schema.INNODB_TRX定位等待事务,再通过INNODB_LOCK_WAITS关联锁源,MySQL 8.0+须用performance_schema.data_locks与data_lock_waits细化锁类型及记录,辅以SHOW PROCESSLIST识别MDL等非InnoDB锁。

查 information_schema.INNODB_TRX 看谁在等、等了多久
这是最直接的入口,INNODB_TRX 记录所有活跃事务,关键字段是 TRX_STATE(值为 LOCK WAIT 表示正在等锁)、TRX_STARTED(事务开始时间)、TRX_MYSQL_THREAD_ID(对应线程 ID)。别只盯着 TRX_STATE = 'LOCK WAIT',还要比对 TRX_WAITING(MySQL 8.0.26+ 才有)或结合后续表判断是否真卡住。
常见错误:只查 INNODB_TRX 就下结论,但没确认锁源。比如看到一个事务状态是 LOCK WAIT,却不知道它被哪个事务堵住,容易误判为死锁或孤立等待。
SELECT * FROM information_schema.INNODB_TRX WHERE TRX_STATE = 'LOCK WAIT';- 记下返回结果里的
TRX_MYSQL_THREAD_ID和TRX_QUERY,这是待分析的“受害者” - 注意
TRX_STARTED时间戳——如果等了几十秒还没释放,大概率不是瞬时竞争,而是上游事务没提交或异常挂起
连查 INNODB_LOCK_WAITS 定位锁源和被锁对象
INNODB_LOCK_WAITS 是连接等待方与持有方的关键桥梁,它把“谁在等”和“谁在占”关联起来。核心字段:REQUESTING_TRX_ID 对应 INNODB_TRX.TRX_ID(等待者),BLOCKING_TRX_ID 对应另一个 TRX_ID(持有锁的事务)。
使用场景:当你从上一步拿到等待事务 ID 后,用它查这个表,就能立刻知道是哪个事务、哪个线程在挡路。但要注意——INNODB_LOCK_WAITS 只在真正发生等待时才记录,如果锁已释放或尚未触发等待,这里为空。
- 执行
SELECT * FROM information_schema.INNODB_LOCK_WAITS;,确认是否有匹配的等待链 - 把结果中的
BLOCKING_TRX_ID拿去查INNODB_TRX,找到对应线程 ID(TRX_MYSQL_THREAD_ID)和当前 SQL(TRX_QUERY) - 若查询为空,不代表没锁争用——可能锁刚释放、或事务处于非等待态(如已获得锁但未提交),需配合
INNODB_LOCKS(MySQL 5.7)或INNODB_METRICS+performance_schema.data_locks(MySQL 8.0+)进一步排查
MySQL 8.0+ 必看 performance_schema.data_locks 和 data_lock_waits
MySQL 5.7 的 INNODB_LOCKS 和 INNODB_LOCK_WAITS 在 8.0 中已被标记为废弃,实际生产环境(尤其 8.0.24+)必须转向 performance_schema 下的新表。它们更细粒度:能区分行锁、间隙锁、插入意向锁,还能看到具体锁定的索引名和记录主键值。
性能影响小,但默认可能未开启。确保 performance_schema 已启用,且相关消费者已打开:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'global_instrumentation';
- 查谁持有哪些锁:
SELECT ENGINE_TRANSACTION_ID, INDEX_NAME, LOCK_TYPE, LOCK_MODE, LOCK_DATA FROM performance_schema.data_locks; - 查等待关系:
SELECT * FROM performance_schema.data_lock_waits;(字段名与旧表不同,BLOCKING_ENGINE_TRANSACTION_ID对应持有者) -
LOCK_DATA列显示的是被锁记录的主键值(如123)或范围(如min, 456),这是定位业务逻辑卡点的关键线索
别漏掉 SHOW PROCESSLIST 和 INNODB_SYS_LOCKS 辅助验证
SHOW PROCESSLIST 不是替代方案,而是交叉验证工具。它能看到线程状态(如 Waiting for table metadata lock 或 Updating),这对识别非 InnoDB 层锁(如 MDL 锁)至关重要——这类锁不会出现在 INNODB_TRX 里,但会让查询彻底卡死。
INNODB_SYS_LOCKS(仅 5.7)或 performance_schema.data_locks(8.0+)提供底层锁结构,但字段抽象(如 LOCK_TRX_ID 是内部 ID,需关联 INNODB_TRX 转换为线程 ID),新手容易绕晕。
- 运行
SHOW FULL PROCESSLIST;,重点关注State列含lock、wait、metadata的行 - 若发现
State: Waiting for table metadata lock,说明是 DDL 操作(如ALTER TABLE)阻塞了 DML,此时要查INFORMATION_SCHEMA.PROCESSLIST找出长事务或未关闭的连接 - 对
INNODB_SYS_LOCKS,只建议在确认是 InnoDB 行锁问题后,用LOCK_TRX_ID去反查INNODB_TRX,避免陷入 ID 映射混乱
锁排查不是单表扫描,是“等待事务 → 锁关系 → 持有者详情 → 外部状态”四步闭环。最容易被忽略的是元数据锁(MDL)和显式锁(SELECT ... FOR UPDATE 后未提交)混在一起的情况——这时候 INNODB_TRX 里看不到等待,但 PROCESSLIST 里线程挂着不动,得立刻切过去看。


















