开启死锁日志获取信息,2. 分析事务锁等待关系与SQL,3. 优化索引和执行顺序,4. 缩短事务并加重试机制,核心是通过日志定位死锁原因并优化SQL、索引及事务设计。

MySQL死锁问题会影响业务正常运行,排查和诊断需要系统性方法。关键在于获取死锁信息、分析事务执行顺序,并优化SQL或事务设计。
1. 开启死锁日志(InnoDB状态监控)
MySQL的InnoDB引擎会在发生死锁时自动生成死锁日志,但默认不记录到错误日志中。要排查死锁,先确保能捕获相关信息。
说明:InnoDB每次检测到死锁,会将详细信息写入其内部的死锁日志缓冲区。可通过以下方式查看:
- 执行 SHOW ENGINE INNODB STATUS\G,在输出结果中查找 “LATEST DETECTED DEADLOCK” 部分,包含最近一次死锁的时间、事务信息、SQL语句、锁类型和等待关系。
- 启用 innodb_print_all_deadlocks = ON(推荐),将所有死锁记录写入MySQL错误日志,便于长期监控和审计。
2. 分析死锁日志内容
从死锁日志中提取关键信息,还原两个或多个事务的并发执行场景。
关注点包括:- 事务时间戳:哪个事务先开始,有助于判断等待顺序。
- 事务持有的锁:例如对某行加了X锁或S锁,锁模式是记录锁、间隙锁还是Next-Key锁。
- 事务等待的锁:明确阻塞点,比如事务A持有行锁却等待事务B释放另一行锁。
- 涉及的SQL语句:定位具体操作,如 UPDATE 或 DELETE 的 WHERE 条件是否命中索引。
- 资源等待图:两个事务互相等待对方持有的锁,形成闭环,即为死锁。
3. 定位SQL与索引问题
多数死锁源于不合理的SQL执行计划或缺少索引。
- UPDATE/DELETE 语句未使用索引,导致全表扫描并加大量行锁。
- 不同事务以不同顺序访问相同数据行,增加循环等待概率。
- 使用间隙锁(Gap Lock)或 Next-Key 锁,在范围更新时容易产生冲突。
检查相关SQL的执行计划(EXPLAIN),确保 WHERE 条件走索引。尽量让事务按相同顺序操作多行数据,减少交叉加锁可能。
4. 优化事务与应用逻辑
缩短事务生命周期,降低死锁概率。
- 减少事务中SQL数量,避免长事务。
- 提交频率提高,及时释放锁资源。
- 在应用层重试机制中捕获死锁错误(MySQL错误码 1213),自动重试事务。
- 考虑使用乐观锁替代悲观锁,减少数据库层面的锁竞争。
基本上就这些。定期查看死锁日志,结合业务逻辑分析,多数死锁问题可定位并解决。不复杂但容易忽略的是索引设计和事务顺序控制。










