mysql 8.0 锁监控范式切换:依赖 performance_schema.data_locks 实时、主动、可 join 查询锁状态,而 5.7 仅靠 innodb_locks 瞬时快照且需锁等待触发,功能受限、不可靠。

MySQL 8.0 的锁监控是实时、可查、可 JOIN 的;5.7 基本只能靠碰运气截取瞬时快照,且必须有锁等待才能看到锁。
INFORMATION_SCHEMA.INNODB_LOCKS 在 5.7 中几乎不可用
这个视图在 5.7 中只在真正发生锁等待时才填充数据,且内容极简:只显示冲突双方的 lock_trx_id、lock_mode、lock_data,不体现锁类型(比如分不清是 X,GAP 还是 X,REC_NOT_GAP),也不展示表级意向锁(IX)或线程上下文。
常见误操作:
- 直接
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS—— 大概率返回空结果,误以为“没锁”,其实是没触发等待 - 依赖该视图做自动化监控 —— 数据稀疏、结构不稳定,脚本极易失效
- 想查某个事务持有哪些锁?做不到。它只反映“谁在等谁”,不反映“谁持有谁”
performance_schema.data_locks 是 8.0 的事实标准
从 8.0 开始,performance_schema.data_locks 成为唯一可靠、主动暴露锁状态的入口。它每行代表一个锁对象,包含 ENGINE、THREAD_ID、LOCK_TYPE(TABLE 或 RECORD)、LOCK_MODE(如 X,GAP、X,REC_NOT_GAP)、LOCK_DATA(具体记录值或间隙边界)。
实操要点:
- 不需要等待冲突发生,只要事务加了锁(哪怕还没提交),就能立刻查到
- 支持
JOIN performance_schema.threads关联线程信息,能定位到 SQL、用户、主机 - 配合
performance_schema.data_lock_waits可查等待链,比SHOW ENGINE INNODB STATUS更稳定、更结构化 - 注意:必须开启
performance_schema且对应消费者已启用(如setup_consumers中events_transactions_current和data_locks需为YES)
SHOW ENGINE INNODB STATUS 输出格式已变,旧脚本大概率解析失败
5.7 的 SHOW ENGINE INNODB STATUS\G 中 LOCK WAIT 段落是扁平文本,字段位置固定;8.0 改为结构化块(含 TRANSACTION、HELD LOCKS、WAITING FOR THIS LOCK TO BE GRANTED 等明确 section),字段顺序和嵌套层级都不同。
典型踩坑点:
- 硬写正则去匹配
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:—— 8.0 里这行可能不存在,或被拆成多行 - 依赖
lock_trx_id出现在某一行第 N 列 —— 8.0 中该字段在 TRANSACTION 块内,且格式为TRANSACTION 42196123456789 - 没开
innodb_print_all_deadlocks = ON,error log 里死锁记录为空 —— 5.7 默认不记,8.0 必须显式开启才写全量
真正容易被忽略的是:8.0 的锁监控能力不是“增强”,而是范式切换——你不能再用 5.7 的思路去“抓快照”,而要像查普通表一样持续查询 performance_schema.data_locks,并接受它带来的轻微性能开销(默认已启用,无需额外配置,但要注意 performance_schema_max_table_instances 是否够用)。











