sys.innodb_lock_waits查不到数据主因是底层数据链断裂:mysql 8.0中该视图依赖performance_schema.data_locks、data_lock_waits及innodb_trx联动生成,若performance_schema未启用、相关consumers关闭或用户缺select/process权限,视图将返回空或字段缺失。

直接查 sys.innodb_lock_waits 就能定位锁源头,但必须确认它底层数据已就绪——MySQL 8.0 中它不依赖已删除的 INNODB_LOCKS 表,而是靠 performance_schema.data_locks 和 INNODB_TRX 联动生成,一旦消费者未启用或权限不足,视图会返回空或字段缺失。
为什么 sys.innodb_lock_waits 查不到数据?
这不是你 SQL 写错了,也不是没锁,而是视图背后的数据链断了:
-
sys.innodb_lock_waits在 MySQL 8.0+ 是一个“合成视图”,不读INFORMATION_SCHEMA.INNODB_LOCKS(该表已被物理移除),而是 JOINperformance_schema.data_locks+performance_schema.data_lock_waits+INFORMATION_SCHEMA.INNODB_TRX - 如果
performance_schema未启用,或data_locks/data_lock_waits的 consumers 被关闭(比如consumer_events_statements_current或events_transactions_current设为NO),视图就查不到任何行 - 普通账号默认无权访问
performance_schema下的锁表,SELECT会静默跳过对应字段,导致blocking_query、waiting_query为空,甚至整行消失
查之前必须做的三件事
执行以下检查,缺一不可:
- 确认
performance_schema已开启:SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME = 'performance_schema';结果必须是ON - 检查锁相关 consumers:
SELECT NAME, ENABLED FROM performance_schema.setup_consumers WHERE NAME IN ('global_instrumentation', 'thread_instrumentation', 'events_statements_current', 'events_transactions_current');所有值应为YES - 授予必要权限:
GRANT SELECT ON performance_schema.* TO 'your_user'@'%'; GRANT PROCESS ON *.* TO 'your_user'@'%'; FLUSH PRIVILEGES;
sys.innodb_lock_waits 字段怎么用才不踩坑?
它的字段名很直白,但几个关键字段容易误读:
-
waiting_pid和blocking_pid是PROCESSLIST.ID,可直接用于KILL CONNECTION xxx,但别急着 KILL——先看blocking_query是否为空;若为空,说明阻塞事务只执行了BEGIN或已跑完 SQL 但没COMMIT -
lock_type = 'RECORD'表示行级锁冲突,lock_type = 'TABLE'多半是 MDL 锁(如ALTER TABLE被卡),这时得查sys.schema_table_lock_waits,不是这个视图 -
wait_age是秒级精度,但注意:它从trx_wait_started开始计,而该时间戳在事务刚进入 LOCK WAIT 状态时才写入,所以刚卡住的等待可能显示为 0 -
sql_kill_blocking_connection字段生成的是完整KILL CONNECTION语句,复制执行即可,但它不会判断业务上下文——比如阻塞源是核心定时任务,KILL 可能引发数据不一致
当 sys.innodb_lock_waits 返回空时怎么办?
空结果 ≠ 没锁等待,只是当前没有满足“等待态”的活跃链。此时要转向更底层的确认方式:
- 先执行
SHOW ENGINE INNODB STATUS\G,翻到LATEST DETECTED DEADLOCK或TRANSACTIONS区块,找状态为LOCK WAIT的事务 ID - 再查
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_state = 'LOCK WAIT';—— 如果有结果,说明确实在等,只是sys.innodb_lock_waits因数据链问题没聚合出来 - 最后查
performance_schema.data_lock_waits原生表:SELECT * FROM performance_schema.data_lock_waits LIMIT 1;,它比 sys 视图更接近内核,只要 consumers 开着,它就不会空
真正容易被忽略的点是:视图里看到的 blocking_query 很可能是空的,但这不代表没 SQL;它只记录事务中**最近一条执行的语句**,而长事务可能早已执行完所有逻辑,只剩一个未提交的壳子攥着锁。这时候必须结合 trx_started 时间和 trx_state 判断是否是“睡着的事务”。











