mysql 8.0死锁检测更激进:后台持续维护wait-for graph,环一形成即毫秒回滚;5.7仅超时后全量扫描,延迟高、日志少、监控视图已废弃,需改用performance_schema.data_lock_waits。

MySQL 8.0 的死锁检测更激进、响应更快,但 CPU 开销更高;5.7 是被动触发、延迟高、日志少——这不是配置开关变了,而是底层 wait-for graph 维护方式彻底重写。
死锁检测触发时机与响应延迟差异
5.7 只在事务等锁超时(默认 innodb_lock_wait_timeout=50 秒)后才启动一次全图扫描;8.0 默认开启 innodb_deadlock_detect=ON,后台线程持续维护等待图,环一形成就立刻回滚,通常在毫秒级完成。
- 实测中,相同热点更新场景下,8.0 的
innodb_row_lock_waits计数增长变慢,不是锁变轻了,而是锁被更快释放了 - 若业务是低并发单行更新,几乎不触发死锁,8.0 的持续图维护反而带来无谓 CPU 消耗
- 5.7 中一个事务卡住可能拖垮整个连接池;8.0 能快速切掉冲突事务,提升整体吞吐稳定性
死锁日志输出方式完全不同
5.7 只在死锁发生时往 error log 写一条简略记录,且默认不开启全量记录;8.0 必须同时打开两个参数才能看到完整信息:innodb_deadlock_detect=ON(检测开关) + innodb_print_all_deadlocks=ON(日志开关)。
- RDS 实例还需额外设
log_error_verbosity = 3,否则连堆栈都看不到 - 线上刚升级发现死锁频发但 error log 空空如也 → 八成是漏配
innodb_print_all_deadlocks -
innodb_print_all_deadlocks会持续写磁盘,生产环境只建议问题定位期开启,查完立即关
锁等待监控入口彻底迁移
5.7 查锁等待靠 INFORMATION_SCHEMA.INNODB_LOCK_WAITS,8.0 已废弃该视图,唯一可靠入口是 performance_schema.data_lock_waits。
- 沿用 5.7 脚本查
INNODB_LOCK_WAITS返回空,不代表没锁等待,只是视图已失效 - 必须确认
performance_schema已启用,且对应 consumer(如events_transactions_current)为ENABLED - 执行
SELECT * FROM performance_schema.setup_consumers WHERE NAME LIKE 'transactions%';验证状态
高并发下要不要关掉死锁检测?
可以关,但行为后果完全不同:8.0 关掉 innodb_deadlock_detect=OFF 后,依赖 innodb_lock_wait_timeout 被动超时;5.7 关掉后,死锁事务会永久挂起,无 fallback。
- 仅在确认业务几乎无死锁(如纯主键更新、无间隙锁场景)且 CPU 压力极高时考虑关闭
- 关掉后必须配套应用层重试逻辑 + 显式设置合理的
innodb_lock_wait_timeout(比如 60 或 120) - 8.0 的
innodb_lock_wait_timeout默认值是 31536000 秒(1 年),不显式设容易误触超时
真正容易被忽略的是:8.0 的死锁检测升级不是“更准”,而是“更勤”——它用 CPU 换确定性。你看到的“性能提升”,往往来自锁链被主动掐断,而非单次操作变快;一旦监控或日志配置没跟上,问题会藏得更深。











