一眼判断是否有锁等待应先执行SHOW STATUS LIKE 'innodb_row_lock_current_waits',若返回值大于0说明当前存在行锁等待;该值为瞬时快照,需结合innodb_row_lock_time_avg突增情况综合判断。

怎么一眼看出当前有没有锁等待
直接看 SHOW STATUS LIKE 'innodb_row_lock_current_waits';——如果返回值大于 0,说明此刻就有事务卡在行锁上,正在等别人释放锁。这是最轻量、权限要求最低、响应最快的初筛方式。
- 它不依赖
INFORMATION_SCHEMA权限,普通账号也能查 - 注意:这个值是瞬时快照,不是累计值;归零不代表问题消失,可能只是锁刚释放
- 搭配
SHOW STATUS LIKE 'innodb_row_lock_time_avg';一起看,如果平均等待时间突然飙升(比如从 0.1ms 跳到 50ms+),大概率有慢事务或未提交事务拖累 -
SHOW OPEN TABLES WHERE In_use > 0;只反映表级锁或元数据锁(如DROP TABLE中卡住),对 InnoDB 行锁完全不敏感,别指望靠它发现 UPDATE 卡住的问题
怎么查谁在等、谁在挡路(MySQL 5.7 及以前)
核心靠三张表联动:INNODB_TRX 看事务状态,INNODB_LOCK_WAITS 找等待关系,再回查 INNODB_TRX 定位阻塞源头。
- 先筛出等待中的事务:
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_state = 'LOCK WAIT'\G;关注trx_wait_started(卡了多久)、trx_query(被堵的 SQL)和trx_mysql_thread_id(对应PROCESSLIST的 ID) - 再查谁挡着:
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS\G;拿到blocking_trx_id,再去INNODB_TRX里查它在干啥、是否长时间RUNNING且没提交 - ⚠️ 坑:
INNODB_LOCKS在 MySQL 8.0 已废弃,5.7 用它还能看到锁对象细节(比如lock_mode: X、lock_table: `test`.`t1`),但 8.0 必须切到performance_schema.data_locks
MySQL 8.0 怎么查锁等待(推荐方式)
放弃 INNODB_LOCKS 和 INNODB_LOCK_WAITS,改用 performance_schema 的 data_locks 和 data_lock_waits——字段更清晰,支持库表过滤,且与实际执行计划绑定更强。
- 确认已启用:
SELECT VARIABLE_VALUE FROM performance_schema.setup_consumers WHERE NAME = 'global_instrumentation';应为YES;若否,需先UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'global_instrumentation'; - 查谁在等谁:
SELECT r.OBJECT_NAME, r.LOCK_MODE AS requested_mode, b.LOCK_MODE AS blocking_mode, r.OWNER_THREAD_ID AS waiting_thread, b.OWNER_THREAD_ID AS blocking_thread FROM performance_schema.data_lock_waits w JOIN performance_schema.data_locks r ON w.REQUESTING_ENGINE_LOCK_ID = r.ENGINE_LOCK_ID JOIN performance_schema.data_locks b ON w.BLOCKING_ENGINE_LOCK_ID = b.ENGINE_LOCK_ID; - 只查某库的锁:
SELECT * FROM performance_schema.data_locks WHERE OBJECT_SCHEMA = 'your_db';,避免全实例扫描干扰判断 - ⚠️ 坑:默认
performance_schema不采集锁事件,必须确保setup_instruments中wait/lock/innodb/...类仪器已开启,否则data_locks为空
怎么拿到完整上下文(死锁、长等待、复杂嵌套)
SHOW ENGINE INNODB STATUS\G 是唯一能一次性看到“事务 + 锁 + 死锁现场 + 等待图”的命令,不能跳过。
- 重点盯
TRANSACTIONS部分:每个事务下面会标LOCK WAIT,并给出它正在等的lock_id和已持有的锁列表 - 死锁必看
LATEST DETECTED DEADLOCK:里面包含两个事务各自的 SQL、加锁顺序、锁模式(X排他 /S共享)、最终哪个被回滚——这是复现和修复的黄金依据 - ⚠️ 坑:
SHOW ENGINE INNODB STATUS输出是循环缓冲区,只保留最近一次死锁和部分事务快照;如果没及时执行,就丢了。卡顿时要立刻跑,别等“稍后” - 配合
SHOW FULL PROCESSLIST;补全被截断的trx_query,尤其当 SQL 较长时,INNODB_TRX里只显示前 1024 字符
锁等待不是静态快照,而是动态争用过程。查得慢一秒,锁可能就释放了;权限少一项,关键字段就为空;版本差一丁点,表名就报错。真正卡住的时候,别纠结“该不该查”,先跑 innodb_row_lock_current_waits 和 SHOW ENGINE INNODB STATUS\G ——剩下的,边看边调。


















