开启innodb锁监控需执行set global innodb_status_output_locks = on(5.6.16+)或set global innodb_lock_monitor = on(旧版),生效后每15秒将锁等待详情输出至错误日志的transactions和lock wait段,需存在真实锁等待才能看到waiting记录。

如何开启 Innodb_lock_monitor 并确认它在工作
Innodb_lock_monitor 不是独立服务,而是 InnoDB 的一个诊断开关,启用后会让 InnoDB 在错误日志中周期性输出当前锁等待、事务和锁结构的详细信息。它不会实时刷新,也不影响运行中的锁行为,只增加日志输出量。
关键点:它必须通过设置全局变量 innodb_status_output_locks(MySQL 5.6.16+)或旧版的 innodb_lock_monitor(已废弃)来启用;直接写入配置文件无效,且需要 SUPER 权限。
- MySQL 5.6.16 及以后版本:执行
SET GLOBAL innodb_status_output_locks = ON; - MySQL 5.6.15 及更早:用
SET GLOBAL innodb_lock_monitor = ON;(但该变量在 5.7 中被移除) - 确认是否生效:
SHOW VARIABLES LIKE 'innodb_status_output_locks';返回ON - 注意:该设置重启 MySQL 后失效,如需持久化,须在
my.cnf中添加innodb_status_output_locks = ON(仅 MySQL 5.6.16+ 支持配置文件方式)
锁信息实际输出在哪?怎么看
启用后,InnoDB 每 15 秒自动调用 SHOW ENGINE INNODB STATUS 并将完整输出追加到 MySQL 错误日志(error_log),而非慢查询日志或 general log。锁详情集中在 “TRANSACTIONS” 和 “LOCK WAIT” 部分,其中包含:
- 每个事务的 ID、状态、持有锁列表(
HELD LOCKS)、等待锁(WAITING FOR THIS LOCK TO BE GRANTED) - 锁类型(
RECORD LOCKS/TABLE LOCK)、模式(S,X,IS,IX)、行键值(space id 123 page no 456 n bits 72) - 阻塞链关系:例如 “Trx id 123456789 is waiting for lock… while holding…”
示例片段(截取自 error_log):
---TRANSACTION 123456789, ACTIVE 12 sec fetching rows mysql tables in use 1, locked 1 LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s) MySQL thread id 1001, OS thread handle 1402..., query id 2000 localhost root updating UPDATE t1 SET v = v + 1 WHERE id = 100; ------- TRX HAS BEEN WAITING 12 SEC FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 123 page no 456 n bits 72 index PRIMARY of table `test`.`t1` trx id 123456789 lock_mode X locks rec but not gap waiting
为什么开了却看不到锁等待信息
常见原因不是配置失败,而是没有“正在发生的锁等待”。Innodb_lock_monitor 只在有活跃锁冲突时才在输出中展示 WAITING 行;若所有事务都顺利提交/回滚,你只会看到事务列表和它们持有的锁,没有 “WAITING FOR” 字样。
- 测试是否真起作用:开两个会话,会话 A 执行
BEGIN; UPDATE t1 SET x=1 WHERE id=1;(不 COMMIT);会话 B 执行相同语句 —— 此时 B 阻塞,再查 error_log 就会出现 WAITING 记录 - 日志级别太低(如
log_error_verbosity = 1)可能过滤掉 INNODB STATUS 输出,建议设为3 - 错误日志路径不对:确认
SELECT @@log_error;指向的位置,并检查文件权限和磁盘空间 - MySQL 8.0.12+ 默认关闭
innodb_status_output,需同时设为ON才能让 INNODB STATUS 被写入日志
性能与线上使用风险提醒
每 15 秒全量输出 SHOW ENGINE INNODB STATUS 内容,对高并发实例会造成明显 I/O 和日志体积压力,尤其当锁结构复杂(成百上千行锁)时,单次输出可达 MB 级别。
- 禁止在生产高峰长期开启;仅用于临时排查锁等待问题,定位后立即关闭:
SET GLOBAL innodb_status_output_locks = OFF; - 不要依赖它做实时监控 —— 它不是锁事件流,而是快照,且间隔固定、不可调
- 替代方案更可靠:MySQL 8.0+ 推荐查
performance_schema.data_locks和data_lock_waits表,支持 SQL 查询、无日志膨胀 - 注意:即使关闭
innodb_status_output_locks,只要innodb_status_output = ON,基础状态(不含锁细节)仍会每 15 秒输出,可一并关掉
真正难的是从几十万行日志里快速定位哪两行事务在互相卡住 —— 建议配合 grep -A 20 -B 5 "WAITING FOR" 或用 pt-deadlock-logger 解析,别手动翻。











