




MySQL自动回滚死锁事务并报错1213,应用需捕获该错误、对竞争逻辑重试1–2次(指数退避),同时开启innodb_print_all_deadlocks记录全量死锁日志,并统一多表更新顺序以根治。
死锁发生后,MySQL 会自动选一个事务回滚,另一个继续执行——你不用手动干预,但必须在应用层捕获错误并重试。
ERROR 1213 (40001): Deadlock found when trying to get lock 怎么办这不是数据库挂了,而是 InnoDB 正常的死锁检测机制在起作用:它发现循环等待后,主动杀死(回滚)其中一个事务,让另一个顺利提交。关键是你得让业务代码“接住”这个错误。
1213 错误码,而不是当作普通异常吞掉或直接报 500SHOW ENGINE INNODB STATUS 能看到什么、怎么看这条命令返回的是最近一次死锁的完整现场快照,重点看 LATEST DETECTED DEADLOCK 下方内容。它告诉你谁等谁、锁了哪些行、执行了什么 SQL。
*** (1) TRANSACTION 和 *** (2) TRANSACTION —— 分别对应两个冲突事务mysql tables in use、locked tables 和 LOCK WAIT 行WAITING FOR THIS LOCK TO BE GRANTED 和 HOLDS THE LOCK(S) 两行,能还原出“谁持有了什么、又在等什么”Trx id 和 OS thread id 可用来关联慢日志或 binlog,但命令本身不保留历史,只存最后一次SHOW ENGINE INNODB STATUS\G
默认只留最近一次,线上排查必须开启全量记录,否则错过就没了。
SET GLOBAL innodb_print_all_deadlocks = ON(需 SUPER 权限)error.log),格式清晰可 grepmy.cnf 的 [mysqld] 段落:innodb_print_all_deadlocks = ON
ROLLBACK 或重启解决死锁手动 ROLLBACK 对已发生的死锁无效——InnoDB 在报错前已经完成回滚;而重启 MySQL 更是危险操作:它会清空所有事务上下文,但无法修复业务逻辑缺陷,还会导致主从延迟、连接闪断、监控报警风暴。
innodb_lock_wait_timeout(超时回滚)和 innodb_deadlock_detect(默认 ON,关了反而更容易卡住)死锁日志里那几行 SQL 看着简单,但背后往往是多个模块耦合修改同一组数据——查日志只是起点,归因要落到代码调用链和资源访问顺序上。