死锁日志解读是什么
死锁是两个事务互相持有对方需要的锁并相互等待,InnoDB 检测到后会主动回滚其中一个。SHOW ENGINE INNODB STATUS 的 LATEST DETECTED DEADLOCK 段会列出两个事务各自的语句、持有锁与等待锁,最后一行说明回滚了谁。读这段日志的目的是还原加锁顺序,而不是只确认「发生过死锁」。
基本信息
| 查看位置 | SHOW ENGINE INNODB STATUS 的 LATEST DETECTED DEADLOCK 段 |
|---|---|
| 关键信息 | 两个事务的语句、持有与等待的锁、回滚结论 |
| 常见成因 | 加锁顺序不一致、缺索引扩大锁范围、唯一键冲突加锁 |
| 应用侧要求 | 能处理错误码 1213 并按策略重试 |
| 辅助表 | 8.0 可用 performance_schema.data_locks 与 data_waits |
典型使用场景
- 线上报错排查:出现 1213 错误时定位冲突语句
- 加锁顺序治理:把多行多表的访问顺序统一成固定顺序
- 缩小锁范围:为条件列补索引,避免锁住大量无关行
- 事务瘦身:拆分长事务缩短持锁时间
- 演练验证:并发压测触发死锁,验证应用重试逻辑有效
- 监控趋势:统计死锁次数变化,判断治理是否见效
查看死锁段
查看死锁段
SHOW ENGINE INNODB STATUS\G
-- 关注 LATEST DETECTED DEADLOCK
-- (1) TRANSACTION: 语句 A,等待锁记录 X
-- (2) TRANSACTION: 语句 B,持有 X,等待 A 的锁
-- WE ROLL BACK TRANSACTION (1)
-- 8.0 可用数据字典表查看当前锁与等待关系
SELECT ENGINE_TRANSACTION_ID, OBJECT_NAME, LOCK_TYPE, LOCK_MODE, LOCK_DATA
FROM performance_schema.data_locks LIMIT 20;
SELECT * FROM performance_schema.data_lock_waits\G
SHOW GLOBAL STATUS LIKE 'Innodb_deadlocks'; -- 死锁累计次数日志段落读法
| 内容 | 含义 | 用途 |
|---|---|---|
| TRANSACTION 1 / 2 | 参与死锁的两个事务 | 定位应用侧对应的业务操作 |
| 语句与事务信息 | 每个事务最后执行的 SQL | 还原冲突发生的具体操作 |
| HELD / WAITING 锁 | 持有与等待的锁记录 | 判断加锁顺序谁先谁后 |
| LOCK_MODE | 锁类型,如 X 或 S 及 gap 标记 | 识别间隙锁带来的额外冲突 |
| 最后一行结论 | InnoDB 回滚了哪个事务 | 确认哪个请求需要重试 |
死锁不是错误而是并发机制:InnoDB 会自动选择代价较小的事务回滚,应用侧必须能处理 1213 错误并按策略重试。
减少死锁的常见手段:按固定顺序访问多表或多行(例如先排序主键再更新)、为条件列补索引缩小锁范围、把大事务拆小以缩短持锁时间。