MySQL 5.7 不支持 innodb_print_all_deadlocks 参数,该变量首次引入于 MySQL 8.0.21;5.7 中执行相关查询会报“Unknown system variable”,配置会导致启动失败或静默忽略,死锁日志仅能通过定期抓取 SHOW ENGINE INNODB STATUS 的 LATEST DETECTED DEADLOCK 区块获取。

innodb_print_all_deadlocks 在 MySQL 5.7 中根本不存在,配置它不会生效,反而会导致 MySQL 启动失败或静默忽略。
你看到的教程说“设为 ON 就能记录每次死锁”,基本是把 MySQL 8.0.21+ 的行为套用到了 5.7 上 —— 这是版本混淆导致的典型误操作。
为什么 SHOW VARIABLES LIKE 'innodb_print_all_deadlocks' 会报错?
执行 SELECT @@innodb_print_all_deadlocks; 或 SHOW VARIABLES LIKE 'innodb_print_all_deadlocks'; 时,MySQL 5.7 直接返回 Unknown system variable。这不是权限或配置顺序问题,而是该变量压根没被实现。
- 该参数首次引入是在 MySQL 8.0.21,5.7 所有小版本(包括 5.7.40)均不支持
- 在 my.cnf 中硬加
innodb_print_all_deadlocks = ON,MySQL 5.7 启动时会报错退出,error log 中出现类似unknown variable 'innodb_print_all_deadlocks' - 即使启动成功(某些打包版本可能忽略未知参数),日志里也绝不会出现
*** (1) TRANSACTION:这类完整死锁块
MySQL 5.7 真正可用的死锁日志方案
5.7 只保留最近一次死锁的完整上下文,且仅存在于内存中。要捕获多次死锁,必须靠组合手段:
- 确保
log_error已启用(默认通常开启),路径可写:SHOW VARIABLES LIKE 'log_error'; - 死锁发生时,error log 里只有一行提示:
[ERROR] [MY-013113] [InnoDB] Deadlock found when trying to get lock; try restarting transaction—— 没有事务堆栈 - 完整死锁详情只在
SHOW ENGINE INNODB STATUS\G的LATEST DETECTED DEADLOCK区块里,但每次新死锁会覆盖前一次 - 必须靠外部脚本定期抓取:例如每 5 秒执行一次
mysql -e "SHOW ENGINE INNODB STATUS\G" >> /tmp/innodb_status.log,并提取LATEST DETECTED DEADLOCK块 - 脚本需具备
PROCESS权限,且要处理输出截断(status 输出可能超 64KB)、并发阻塞(该命令串行执行)等问题
容易被忽略的关键限制
很多团队以为开了 log_error 就等于有了死锁录像带,实际远非如此:
-
SHOW ENGINE INNODB STATUS是单线程操作,高频轮询(如每秒一次)会严重拖慢 MySQL,甚至卡住业务查询 - 抓取脚本若没加锁或限流,多个实例并发执行
SHOW ENGINE INNODB STATUS会排队等待,导致采集间隔严重失真 - error log 中那行
Deadlock found提示本身不带时间戳精度(只到秒级),无法与应用层报错精确对齐 - 5.7 不支持
performance_schema.data_locks等 8.0+ 的锁视图,排查锁等待只能依赖INFORMATION_SCHEMA.INNODB_TRX+INNODB_LOCK_WAITS,而后者只反映“当前正在等待”的关系,不是历史快照
真正难的不是找日志,而是从零散的 LATEST DETECTED DEADLOCK 快照和 error log 时间点里,拼出两个事务真实的加锁顺序 —— 这需要你对索引结构、隔离级别、SQL 执行路径有足够判断力。别指望一个参数开关就能自动给出答案。


















