跨大版本升级后死锁增多,根本原因是MySQL 8.0默认行为变化(如更严格的间隙锁、频繁统计更新)暴露了原有事务逻辑缺陷,需通过调整执行计划、索引和关键参数(如innodb_print_all_deadlocks=ON)来精准应对。

跨大版本升级(如 5.7 → 8.0)后死锁增多,**不是因为参数没调对,而是默认行为变化暴露了原有事务逻辑的缺陷**。你没法靠改几个 innodb_* 参数“堵住”死锁,但可以精准关闭或调整那些在新版本中突然激化冲突的机制。
为什么升级后死锁日志突然变多?
MySQL 8.0 对间隙锁(gap lock)更严格,REPEATABLE READ 下非唯一索引的范围查询会加更多 Next-Key 锁;同时统计信息自动更新更频繁,导致优化器偶尔走错执行计划——原来只锁 2 行,现在锁了 200 行,和其他事务交叉概率飙升。
- 检查是否触发了隐式锁升级:执行
EXPLAIN FORMAT=TRADITIONAL SELECT ... FROM t WHERE status = 'pending',若type是index或ALL、key为NULL,说明缺失索引,升级后全表扫描+全表行锁就是死锁温床 - 对比升级前后
SHOW VARIABLES LIKE 'transaction_isolation',8.0 默认仍是REPEATABLE-READ,但如果你的应用没显式设隔离级别,驱动或 ORM 可能悄悄降级到READ-COMMITTED,造成语义不一致 - 别忽略
innodb_lock_wait_timeout值是否被重置:5.7 默认是 50,8.0 仍为 50,但某些升级脚本或配置模板会误设为 10,让原本“卡住”的事务更快报Deadlock found when trying to get lock而非等待超时
必须改的三个关键参数
不是“推荐”,是升级后立即验证并按需覆盖的硬性动作:
-
innodb_print_all_deadlocks = ON:默认是 OFF,不打开就只能看到最近一次死锁;升级后第一件事就是写进my.cnf并SET GLOBAL生效,否则你连哪条 SQL 在冲突都看不到 -
innodb_deadlock_detect = ON:虽然默认开启,但某些云厂商 MySQL 实例会关掉以降低 CPU 开销;一旦关闭,死锁不会被检测,事务会卡在Waiting for table metadata lock或无限等待,比报错更难排查 -
transaction_isolation = REPEATABLE-READ:显式声明,防止 ORM 或连接池因协议兼容问题协商出意外级别;如果业务确认不需要可重复读(比如只是查状态页),可改为READ-COMMITTED直接禁用间隙锁
哪些参数改了反而更危险?
别碰这些“看起来能缓解死锁”的选项:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
innodb_lock_wait_timeout调大:只会让事务挂得更久,增加锁持有时间,放大死锁窗口;它解决的是锁等待超时,不是死锁本身 -
innodb_rollback_on_timeout = OFF:旧版建议关掉避免自动回滚,但在 8.0 中该参数已废弃,强行设会导致启动失败 -
innodb_thread_concurrency:设成非 0 值会引入额外调度开销,且无法控制事务加锁顺序,对死锁无实质影响,反而可能拖慢响应
真正要盯住的不是参数,是执行计划和索引
升级后第一次出现死锁,90% 的根因藏在 EXPLAIN 结果里:
- 同一张表,两个事务一个走
idx_user_id,一个走idx_status更新重叠行 → 冲突必然发生;必须统一走同一个联合索引,例如ALTER TABLE t ADD INDEX idx_user_status (user_id, status) - 批量更新用
WHERE id IN (5, 1, 8),但没加ORDER BY id→ InnoDB 加锁顺序不可控;改成WHERE id IN (1, 5, 8) ORDER BY id或应用层排序后再拼 SQL - 热点行更新(如库存扣减)还在用
SELECT ... FOR UPDATE+ 应用层判断 → 改用UPDATE t SET stock = stock - 1 WHERE id = ? AND stock >= 1,靠唯一约束和原子性规避锁竞争
参数只是开关,执行路径才是锁的源头。升级后最该花时间的地方,是把所有高频 DML 的 EXPLAIN 拿出来对照看——有没有新增的 Using filesort、Using temporary,或者 key 从有变成 NULL。










