最轻量定位锁等待的方法是查 information_schema.innodb_trx 表中 trx_state = 'lock wait' 的行,可快速获取卡住的线程 id 和 sql;再通过 trx_mysql_thread_id 关联 processlist 查客户端信息;注意该表仅反映 innodb 层等待,且为快照视图,需多次查询确认。

查 INFORMATION_SCHEMA.INNODB_TRX 看活跃事务和锁等待状态
MySQL 5.6+ 的 INFORMATION_SCHEMA.INNODB_TRX 表直接暴露了当前所有活跃 InnoDB 事务,其中 TRX_STATE 为 LOCK WAIT 的行,就是正在等锁的事务。这是最轻量、最常用的入口。
实操建议:
- 执行
SELECT TRX_ID, TRX_STATE, TRX_MYSQL_THREAD_ID, TRX_QUERY FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_STATE = 'LOCK WAIT';—— 快速定位卡住的线程和 SQL -
TRX_MYSQL_THREAD_ID可直接关联PROCESSLIST查客户端 IP、用户、运行时长:SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = ?; - 注意:该表只反映 InnoDB 层的等待,MyISAM 或表级锁不会出现
连查 INFORMATION_SCHEMA.INNODB_LOCK_WAITS 定位谁在等谁
单看 INNODB_TRX 只知道“在等”,但不知道“等谁”。INNODB_LOCK_WAITS 是关键桥梁表,它记录了等待关系(BLOCKING_TRX_ID → REQUESTING_TRX_ID),配合 INNODB_LOCKS(已弃用)或新版的 INNODB_LOCK_WAITS 关联字段可追溯源头。
实操建议:
- MySQL 8.0.19+ 已移除
INNODB_LOCKS,改用performance_schema.data_locks和data_lock_waits—— 若用旧版本(如 5.7),仍可用INNODB_LOCK_WAITS连查:SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread FROM INFORMATION_SCHEMA.INNODB_TRX b INNER JOIN INFORMATION_SCHEMA.INNODB_LOCK_WAITS w ON b.trx_id = w.BLOCKING_TRX_ID INNER JOIN INFORMATION_SCHEMA.INNODB_TRX r ON r.trx_id = w.REQUESTING_TRX_ID; - MySQL 8.0.20+ 必须用
performance_schema.data_lock_waits,且需确保performance_schema开启且相关 consumer 已启用:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_transactions_current'; - 别漏掉权限:查询这些表需要
PROCESS权限,否则返回空结果
用 SHOW ENGINE INNODB STATUS 拿完整锁上下文
这是最“原始”但也最全的方式——它输出当前 InnoDB 内部状态快照,包含最近的死锁检测、等待队列、持有锁的事务详情、甚至加锁的索引名和记录值。适合深度排查,但输出是大段文本,不易解析。
实操建议:
- 执行
SHOW ENGINE INNODB STATUS\G(注意末尾\G让输出更易读),重点看---TRANSACTION块和SEMAPHORES下的WAITING FOR THIS LOCK TO BE GRANTED部分 - 输出中每个
---TRANSACTION块会标出mysql thread id、query id、SQL 语句,以及是否holds the lock或waiting for this lock to be granted - 该命令每秒最多执行一次(InnoDB 内部有频率限制),频繁调用会返回缓存旧结果;且输出不保证实时性,仅反映最近一次快照
避免被 information_schema 视图延迟误导
很多用户查完 INNODB_TRX 发现没数据,就以为没锁等待——其实是因为 information_schema 表是“快照视图”,不是实时反射。尤其在高并发下,事务可能刚结束、视图还没刷新,或因 MVCC 可见性规则导致部分事务不可见。
实操建议:
- 不要依赖单次查询结果做判断;若怀疑有等待,连续查 2–3 秒间隔的
INNODB_TRX,观察TRX_STATE是否稳定为LOCK WAIT - 确认是否用了
READ COMMITTED隔离级别:该级别下INNODB_TRX中的TRX_ROWS_LOCKED可能为 0,但实际仍在等锁 - 真正要确认锁存在,最可靠的是结合
performance_schema.data_locks(8.0+)或SHOW ENGINE INNODB STATUS输出中的RECORD LOCKS行,看到具体哪条记录被锁住
锁等待不是孤立现象,它背后往往连着慢查询、缺失索引、长事务或应用层未 commit 的连接。查到等待线程后,优先看它的 TRX_STARTED 时间和 TRX_QUERY,再顺藤摸瓜找上游业务逻辑——这才是真正解决问题的起点。











