MySQL 8.0 中 information_schema.innodb_locks 表已被移除,应改用 performance_schema.data_locks;需先启用相关 instruments 和 consumers,否则查询返回空。

MySQL 8.0 查 information_schema.innodb_locks 返回空怎么办
直接查不到,不是你权限或语法错,是这张表在 MySQL 8.0 中已被移除。官方文档明确标注为“deprecated since 5.7, removed in 8.0”。哪怕你执行 SELECT * FROM information_schema.innodb_locks; 不报错,也只会返回空结果集。
常见误操作是照着老教程或 5.7 环境下的笔记硬套——比如看到 lock_mode: X、lock_table: `test`.`t1` 这类字段就以为还能用。实际上,8.0 起所有锁对象信息已统一迁移到 performance_schema.data_locks。
- 确认版本:运行
SELECT VERSION();,若输出以8.开头,就别再查innodb_locks - 替代方案必须启用 instrumentation:执行
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE '%wait/lock%'; - 检查是否已开采集:运行
SELECT VARIABLE_VALUE FROM performance_schema.setup_consumers WHERE NAME = 'global_instrumentation';,结果必须是YES
MySQL 5.7 怎么用 innodb_locks 和 innodb_lock_waits 定位阻塞者
这两张表在 5.7 是有效的联动组合,但要注意字段语义和查询顺序——不能只查一张表就下结论。
innodb_locks 只告诉你“有哪些锁”,不说明谁在等、谁在占;innodb_lock_waits 才给出等待关系,但它只存 ID(如 blocking_trx_id),得回查 innodb_trx 才知道那个事务干了什么、卡了多久。
- 先筛等待中的事务:
SELECT * FROM information_schema.INNODB_TRX WHERE trx_state = 'LOCK WAIT'\G;,重点看trx_wait_started和trx_query - 再查谁挡路:
SELECT * FROM information_schema.INNODB_LOCK_WAITS\G;,拿到blocking_trx_id - 最后定位源头:
SELECT trx_id, trx_mysql_thread_id, trx_started, trx_state, trx_query FROM information_schema.INNODB_TRX WHERE trx_id = '613962';(把上面查到的 ID 填进去) - 注意权限:普通账号默认看不到其他用户的事务,需被授予
PROCESS权限
SHOW STATUS LIKE 'innodb_row_lock_current_waits' 为什么值为 0 却还有卡住的 SQL
这个状态变量只反映“此刻正在发生的行级锁等待”瞬时快照,归零不代表没锁问题——它可能刚释放、也可能根本不是行锁问题。
典型误判场景:DDL 操作卡在 Waiting for table metadata lock,这是元数据锁(MDL),跟 InnoDB 行锁完全无关,innodb_row_lock_* 系列变量对它毫无反应。
- 查 MDL 锁要换路子:看
performance_schema.metadata_locks或结合show processlist状态字段 - 如果
innodb_row_lock_current_waits长期为 0,但innodb_row_lock_time_avg突然飙升(比如从 0.1ms 到 40ms+),说明有短时密集争用,得盯紧应用层事务提交节奏 - 这个指标不体现锁类型细节,仅作初筛;真要定位,必须进
INNODB_TRX或data_locks
为什么查到 trx_state = 'RUNNING' 却没 trx_query 就该警惕
这种事务大概率是“挂着没死、但早该结束了”——比如应用异常断连后未 rollback,或代码里漏了 COMMIT/ROLLBACK。它持续持有锁,却不在执行任何 SQL,是锁等待链最常出现的源头。
尤其在 RR 隔离级别下,一个 SELECT ... FOR UPDATE 后没提交,锁会一直占着;RC 下虽部分锁释放快,但唯一键冲突检查引发的 gap lock 仍可能残留。
- 快速筛查语句:
SELECT trx_id, trx_mysql_thread_id, trx_started, trx_state, trx_query FROM information_schema.INNODB_TRX WHERE trx_state = 'RUNNING' AND (trx_query IS NULL OR trx_query = '') ORDER BY trx_started ASC LIMIT 10; - 别急着
KILL:先用SELECT * FROM performance_schema.threads WHERE THREAD_ID = ?查对应连接的PROCESSLIST_INFO,排除监控探针或定时任务的“假活跃” - 真正麻烦的是那种
trx_operation_state显示'sleeping before entering InnoDB'的事务——它已脱离 SQL 执行阶段,但锁还攥着


















