导读:本期聚焦于小伙伴创作的《如何定位MySQL死锁导致的事务回滚_通过ShowEngineInnoDBStatus查看死锁日志》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何定位MySQL死锁导致的事务回滚_通过ShowEngineInnoDBStatus查看死锁日志》有用,将其分享出去将是对创作者最好的鼓励。

MySQL死锁与事务回滚的基本逻辑

MySQL的InnoDB引擎默认开启死锁检测机制,当两个或多个事务互相持有对方需要的锁,且都处于等待状态时,就会触发死锁。此时InnoDB会选择回滚其中一个事务,让另一个事务继续完成操作,被回滚的事务会收到相应的错误提示。

事务回滚后,该事务执行的所有数据修改操作都会被撤销,业务层需要根据错误码判断是否要重试执行该事务。常见的死锁错误码是1213,错误信息会提示事务被回滚是因为检测到死锁。

使用ShowEngineInnoDBStatus查看死锁日志

当发生死锁后,我们可以通过执行SHOW ENGINE INNODB STATUSG命令获取InnoDB引擎的运行状态,其中就包含最近一次死锁的详细日志信息。这个命令的输出内容较多,我们需要重点关注死锁相关的段落。

执行命令获取状态信息

在MySQL客户端中执行以下命令:

-- 查看InnoDB引擎状态,包含死锁日志
SHOW ENGINE INNODB STATUSG

执行后返回的结果中,找到LATEST DETECTED DEADLOCK段落,这段内容就是最近一次死锁的完整记录。

死锁日志关键内容解析

死锁日志主要包含以下几个部分的信息:

  • 死锁发生的时间,记录为202X-XX-XX XX:XX:XX格式
  • 参与死锁的事务列表,每个事务会标注事务ID、事务状态、持有的锁和等待的锁
  • 每个事务正在执行的SQL语句,方便定位具体业务操作
  • 最终被回滚的事务标识,说明哪个事务被牺牲掉以解除死锁

日志示例解析

以下是一个简化后的死锁日志片段,我们逐一解析内容:

------------------------
LATEST DETECTED DEADLOCK
------------------------
2024-05-20 14:30:22 0x7f8b2c1a3700
*** (1) TRANSACTION:
TRANSACTION 123456, ACTIVE 2 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 10, OS thread handle 140248345583360, query id 123 localhost root updating
UPDATE user SET balance = balance - 100 WHERE id = 1
*** (1) WAITING FOR:
RECORD LOCKS space id 58 page no 3 n bits 72 index PRIMARY of table `test`.`user` trx id 123456 lock_mode X waiting
*** (2) TRANSACTION:
TRANSACTION 123457, ACTIVE 1 sec starting index read
mysql tables in use 1, locked 1
2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 11, OS thread handle 140248345583361, query id 124 localhost root updating
UPDATE user SET balance = balance - 50 WHERE id = 2
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 58 page no 3 n bits 72 index PRIMARY of table `test`.`user` trx id 123457 lock_mode X
*** (2) WAITING FOR:
RECORD LOCKS space id 58 page no 3 n bits 72 index PRIMARY of table `test`.`user` trx id 123457 lock_mode X waiting
*** WE ROLL BACK TRANSACTION (1)

从上面的日志可以看出,事务123456持有id=2的行的排他锁,等待id=1的行的排他锁;事务123457持有id=1的行的排他锁,等待id=2的行的排他锁,形成死锁。最终InnoDB回滚了事务123456,事务123457可以继续执行。

根据死锁日志优化业务

拿到死锁日志后,我们可以从以下几个方向优化业务,减少死锁发生:

  • 统一事务中操作数据的顺序,比如所有事务都按照id从小到大的顺序更新数据,避免出现循环等待锁的情况
  • 尽量缩小事务的范围,减少事务持有锁的时间,避免长事务占用锁资源
  • 给查询和更新语句添加合适的索引,避免行锁升级为表锁,减少锁冲突的概率
  • 对于非核心的事务操作,可以设置合理的锁等待超时时间,避免无限等待

常见问题说明

需要注意的是,SHOW ENGINE INNODB STATUS只会记录最近一次的死锁信息,如果死锁发生后又有新的死锁,之前的日志会被覆盖。如果需要留存所有死锁日志,可以开启InnoDB的死锁日志输出到错误日志的功能,在配置文件中添加innodb_print_all_deadlocks=ON即可。

另外,事务回滚后,业务层捕获到1213错误时,可以根据业务场景选择重试执行该事务,重试时需要注意控制重试次数,避免频繁重试加重数据库负担。

MySQL死锁事务回滚ShowEngineInnoDBStatusInnoDB死锁日志修改时间:2026-07-02 14:09:35

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。