MySQL 5.7及更早版本应查information_schema.INNODB_LOCK_WAITS并关联INNODB_TRX获取线程与SQL,8.0+则优先使用sys.innodb_lock_waits视图,因其字段更直观且自动关联waiting_query和blocking_query;该表仅为实时快照,锁释放即消失,无法查历史。

直接查 INNODB_LOCK_WAITS 表,但得先确认 MySQL 版本
MySQL 5.7 及更早版本没有 sys.innodb_lock_waits 视图,强行用会报错 Table 'sys.innodb_lock_waits' doesn't exist。必须区分版本写查询语句,否则查不到任何阻塞信息。
- MySQL <= 5.7:查
information_schema.INNODB_LOCK_WAITS,再关联INNODB_TRX获取线程 ID 和 SQL - MySQL >= 5.7(含 8.0):优先用
sys.innodb_lock_waits,字段更直观,且自动关联了等待/阻塞双方的waiting_query和blocking_query - 注意:
INNODB_LOCK_WAITS是实时快照,只保留当前正在等待的锁关系,事务一释放锁就消失,不能查历史
SHOW ENGINE INNODB STATUS 输出里关键字段在哪
这条命令输出大而杂,真正有用的阻塞线索藏在 TRANSACTIONS 小节里,不是开头的 LATEST DETECTED DEADLOCK —— 那只是死锁记录,和普通阻塞无关。
- 找
LOCK WAIT字样:每段以---TRANSACTION xxx, ACTIVE y sec开头,若后面跟着LOCK WAIT,说明该事务正卡在等锁 - 看
mysql tables in use和locked tables:确认是否真锁了表或行 - 重点读
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:下面的 lock struct,它告诉你等的是哪把锁、哪个索引、哪一行(如record lock heap no 2) - 别忽略
Trx read view will not see trx with id >= ...这类提示,它可能暗示长事务拖慢了 MVCC 清理
用 SHOW PROCESSLIST 快速定位“卡住”的线程
SHOW PROCESSLIST 不显示锁关系,但它能立刻告诉你哪些线程状态异常,是第一响应工具。
- 关注
State列:值为Locked、Waiting for table metadata lock、Updating但Time超过 30 秒,基本可判定异常 -
Info列被截断?加FULL:用SHOW FULL PROCESSLIST看完整 SQL,否则可能漏掉关键 WHERE 条件 - 别只看
Time:有些线程Time很小但反复出现,可能是短事务高频争抢同一行,需结合INNODB_LOCK_WAITS确认是否真阻塞 - 对比
Id和INNODB_TRX.trx_mysql_thread_id:只有两者一致,才能把PROCESSLIST里的线程和锁等待里的事务对应上
为什么查不到阻塞,但业务明显变慢
常见情况不是“没阻塞”,而是阻塞源不在你预期的位置 —— 比如元数据锁(MDL)、全局读锁、或隐式锁升级。
-
Waiting for table metadata lock:通常由 DDL(如ALTER TABLE)引发,即使没显式加锁,也会阻塞后续所有对该表的读写 - 长事务未提交:查
INNODB_TRX表,看trx_started时间远早于当前时间的事务,它可能没在等锁,但拖慢了 purge 线程,间接导致其他事务变慢 - 非 InnoDB 表:MyISAM 表只有表级锁,
INNODB_LOCK_WAITS完全不记录,只能靠SHOW PROCESSLIST+State判断 - 复制延迟线程:从库上
Slave_SQL_Running_State显示Waiting for dependent transaction,本质也是阻塞,但不在主库锁机制内
真实排查时,INNODB_LOCK_WAITS 给出“谁在等谁”,SHOW ENGINE INNODB STATUS 解释“为什么等”,SHOW PROCESSLIST 告诉你“现在卡在哪”——三者缺一不可,单独依赖任何一个都容易误判。


















