mysql 5.7与8.0锁监控存在本质差异:5.7的innodb_locks仅在锁冲突时显示快照,字段少且无法区分锁类型;8.0的performance_schema.data_locks可实时查询所有会话持锁详情,字段丰富、类型精确,并支持锁等待链分析。

MySQL 5.7 和 8.0 的锁监控不是“换了个表名”,而是监控逻辑、数据粒度和可见性发生了根本变化:5.7 只在发生锁冲突时才暴露部分信息,8.0 则能实时、完整地看到每个会话持有的所有锁。
INFORMATION_SCHEMA.INNODB_LOCKS 在 5.7 中只显示冲突锁
5.7 的 INFORMATION_SCHEMA.INNODB_LOCKS 是个“冲突快照视图”——它不展示事务当前持有哪些锁,只在两个事务互相阻塞(即已形成锁等待)时,才列出双方涉及的锁记录。这意味着:
- 单个事务执行
SELECT ... FOR UPDATE后没被等,INNODB_LOCKS就是空的 - 即使锁已加,只要没冲突,你就看不到它 —— 监控盲区大
- 字段少,只有
lock_trx_id、lock_mode、lock_data等基础项,无法区分是行锁、间隙锁还是临键锁 - 实验中常需手动构造 session1 阻塞 session2,才能触发该视图有输出
performance_schema.data_locks 在 8.0 中可查任意会话持锁详情
8.0 引入 performance_schema.data_locks,本质是把锁状态作为运行时元数据持久化暴露,无需等待冲突即可查询:
- 每个活跃事务(哪怕只是开了事务没执行任何语句)都能在该表中查到其持有的全部锁
- 字段丰富:
THREAD_ID对应连接线程,LOCK_TYPE明确是TABLE还是RECORD,LOCK_MODE区分X,REC_NOT_GAP、X,GAP、X,INSERT_INTENTION等精确类型 - 配合
performance_schema.data_lock_waits,可直接 JOIN 查出谁在等谁、等什么锁、等了多久 - 不再依赖
SHOW ENGINE INNODB STATUS\G这种瞬时快照,适合自动化采集与告警
监控脚本迁移时最容易踩的坑
从 5.7 迁移到 8.0 后,沿用旧监控逻辑会漏掉关键线索:
- 继续用
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS查锁?在 8.0 里这个表已被弃用,查出来是空或报错 - 解析
SHOW ENGINE INNODB STATUS\G中的死锁日志?8.0 输出结构变了,LATEST DETECTED DEADLOCK块内字段顺序和嵌套层级不同,正则匹配易失效 - 没开
innodb_print_all_deadlocks = ON?8.0 默认不记全量死锁到 error log,只靠data_locks又看不到历史回滚事件 - 误以为
data_locks记录数多 = 锁变多了?其实是更真实反映——5.7 下很多锁根本没被看见,8.0 把它们全摊开给你看
真正要盯住的不是“有没有锁”,而是锁的类型分布和等待链是否闭环;data_locks 提供了原始素材,但解读它需要理解 X,GAP 和 X,INSERT_INTENTION 之间为什么能共存、又在哪种条件下会互斥——这点比换 SQL 更关键。











