sys.innodb_lock_waits常查不到等待记录,因其仅实时展示“当前正在发生的锁等待”,事务提交、回滚或超时后记录立即消失,且依赖performance_schema.data_locks/data_lock_waits(需手动启用采集器及对应instruments),同时非super用户默认只能查看自身线程锁信息。

为什么查 sys.innodb_lock_waits 常看不到等待记录?
因为这张视图只展示「当前正在发生的锁等待」,一旦事务提交、回滚或超时中断,对应行就立刻消失。不是历史锁问题的审计表,也不是所有锁都会触发等待——比如间隙锁(gap lock)不阻塞插入时可能根本不上这个视图。
实操建议:
- 必须在锁等待**发生中**执行查询,最好配合
SHOW ENGINE INNODB STATUS\G交叉验证 - 如果刚复现完死锁却查不到,大概率是事务已自动回滚,需改用
information_schema.INNODB_TRX+INNODB_LOCKS(MySQL 5.7)或performance_schema.data_locks(8.0+)补位 -
sys.innodb_lock_waits依赖底层 performance_schema 表,确认已开启:SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE 'wait/lock%';,未启用则全为空
sys.innodb_lock_waits 各字段怎么对号入座?
关键字段不是按字面意思直读的:比如 BLOCKING_TRX_ID 是持有锁的事务 ID,但你要去 INNODB_TRX 里查它对应的 TRX_MYSQL_THREAD_ID 才能关联到线程;WAITING_TRX_ID 同理。最易错的是 WAITING_PID 和 BLOCKING_PID ——它们是 performance_schema 的线程 ID,不是操作系统 PID。
实操建议:
- 先查
SELECT * FROM sys.innodb_lock_waits;拿到BLOCKING_TRX_ID - 再查
SELECT TRX_ID, TRX_MYSQL_THREAD_ID, TRX_QUERY FROM information_schema.INNODB_TRX WHERE TRX_ID = 'xxx';定位阻塞 SQL - 用
SELECT * FROM performance_schema.threads WHERE THREAD_ID = xxx;查线程详情(如用户、命令、运行时间) -
WAITING_LOCK_ID和BLOCKING_LOCK_ID格式形如12345:123:4567,分别对应LOCK_TRX_ID:LOCK_SPACE:LOCK_PAGE,一般只需关注前两段
MySQL 8.0 下 sys.innodb_lock_waits 为啥查不到数据?
8.0 移除了 INNODB_LOCKS 和 INNODB_LOCK_WAITS 这两张旧表,sys.innodb_lock_waits 视图底层改用 performance_schema.data_locks 和 data_lock_waits。但这两个表默认关闭采集,且权限要求更细。
实操建议:
- 启用锁监控:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME = 'transaction';,并确保data_locks和data_lock_waits对应项为 YES - 检查用户权限:
GRANT SELECT ON performance_schema.* TO 'user'@'%';(仅 SELECT 不够,还需 PROCESS 权限才能看到其他线程的锁信息) - 避免用 root 以外账户查 —— 非 super 用户默认只能看到自己线程的锁,
sys.innodb_lock_waits会过滤掉跨线程数据
查到阻塞源后,怎么快速止损?
别直接 KILL 线程,先看事务状态和 SQL 类型。长事务更新没提交、大范围 DELETE、未加索引的 UPDATE 都可能成为锁源头。KILL 之前务必确认:TRX_STATE 是 RUNNING 还是 LOCK WAIT,TRX_ROWS_LOCKED 是否异常高,TRX_QUERY 是否含 FOR UPDATE 或 LOCK IN SHARE MODE。
实操建议:
- 优先让应用侧重试或缩短事务边界,而不是强制 KILL —— KILL 可能导致主从延迟或 binlog 不一致
- 若必须 KILL,用
KILL CONNECTION xxx;(不是KILL xxx;),避免误杀后台线程 - 临时缓解可降低隔离级别:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;,但需评估业务一致性影响 - 真正根治得看执行计划:
EXPLAIN FORMAT=JSON确认是否走索引,避免type: ALL或Extra: Using where; Using filesort
锁等待不是独立现象,它背后连着事务设计、索引质量、SQL 写法三道坎。查 sys.innodb_lock_waits 只是切口,别停在那一行结果上。











