MySQL 5.7 默认不记录死锁详情是因为 innodb_print_all_deadlocks=OFF,仅写入摘要;需设为 ON 才输出含事务ID、SQL、锁信息的完整日志,且需 log_error_verbosity≥3 并确认日志路径与权限正确。

MySQL 5.7 默认不记录死锁详情到 error log,必须显式开启 innodb_print_all_deadlocks 才能输出完整死锁信息(包括事务ID、SQL、等待/持有锁对象等),否则只在客户端报错,error log 里只有模糊提示甚至完全空白。
为什么 error log 里看不到死锁详情?
默认情况下,InnoDB 只把死锁摘要(如 “Deadlock found when trying to get lock”)写入 error log,不展开具体 SQL 和锁资源。这是性能权衡,不是 bug 或配置遗漏。
-
innodb_print_all_deadlocks=OFF(默认值)→ 只记录一行摘要,无上下文 -
innodb_print_all_deadlocks=ON→ 每次死锁都追加一段结构化文本,含两个事务的 SQL、行锁/表锁、等待链、时间戳 - 该变量是动态的,但需注意:它只影响后续发生的死锁,不会补录历史事件
如何启用并验证死锁日志输出?
直接执行 SQL 即可生效,无需重启:
SET GLOBAL innodb_print_all_deadlocks = ON;
验证是否生效:
- 检查变量值:
SELECT @@global.innodb_print_all_deadlocks;应返回1 - 触发一次人为死锁(比如两个会话交叉更新两行),再查 error log:
tail -n 50 /var/lib/mysql/your-host.err - 正确输出开头类似:
*** (1) TRANSACTION:,后面跟事务ID、SQL、LOCK WAIT 等字段
若仍看不到,确认 error log 路径正确(SHOW VARIABLES LIKE 'log_error';),且 mysqld 进程对日志文件有写权限。
常见踩坑点:日志写了但找不到或格式混乱
死锁日志混在 error log 里,容易被忽略或误判为错误信息。关键点:
- 日志不是 JSON 或结构化格式,是纯文本块,每段以
*** (1) TRANSACTION:开头,用空行分隔 - 如果
log_error_verbosity设得太低(如1),可能过滤掉死锁日志;建议设为3(默认值):SET GLOBAL log_error_verbosity = 3; - 不要依赖
general_log或slow_query_log查死锁——它们不记录死锁事件本身 - 审计时建议用脚本 grep 提取:
grep -A 20 -B 5 "DEADLOCK" /var/lib/mysql/your-host.err
死锁日志本身不包含用户账号、主机名等审计元数据,只能定位到 connection_id 和事务 ID;若需关联操作人,得结合 init_connect 记录连接映射,或用 server_audit 插件补全行为链路——单纯靠 error log 做合规审计是不够的。


















