死锁原因与排查
2024年双十一零点,订单服务报警:大量请求超时。
DBA 排查发现,MySQL 出现了死锁:
两个事务互相等待对方持有的锁,形成了死锁。MySQL 检测到后自动回滚了其中一个事务。
【面试官心理】 这道题我用来测试候选人有没有实际处理过死锁的经验。能说出死锁原因的占 50%,能读懂死锁日志的占 20%,能提出完整解决方案的占 10%。死锁是 MySQL 面试的高频问题,因为它是生产环境中真实会遇到的。
一、死锁的本质 🔴
1.1 死锁的定义
死锁:两个或多个事务相互等待对方持有的锁,形成循环等待,无法继续执行。
1.2 死锁的四个必要条件
只要破坏其中一个条件,死锁就不会发生。
1.3 死锁和锁等待的区别
二、死锁的典型场景 🔴
2.1 场景一:批量更新顺序不一致
2.2 场景二:主键和唯一索引的锁冲突
2.3 ❌ 错误理解
候选人原话:"死锁是因为两个事务同时更新同一个资源。"
问题诊断:
- 同一资源的竞争不会导致死锁,只是锁等待
- 死锁的关键是循环等待,不同事务以不同顺序竞争多个资源
- 相同顺序的锁竞争只会导致锁等待,不会死锁
三、死锁日志解读 🟡
3.1 死锁日志结构
3.2 日志关键字段
3.3 排查步骤
四、死锁预防策略 🟡
4.1 固定加锁顺序
核心原则:所有事务按相同顺序获取锁。
4.2 使用低隔离级别
4.3 减少事务持有时间
4.4 使用分布式锁替代数据库锁
⚠️
分布式锁会引入额外的复杂性和网络开销。只有在数据库锁成为性能瓶颈时才考虑使用。
五、死锁监控与处理 🟡
5.1 开启死锁监控
5.2 监控死锁事件
5.3 死锁后的处理
六、生产避坑
6.1 批量操作的死锁陷阱
6.2 外键和索引的关系
【面试官心理】 能说出"外键删除锁整表"这个坑的候选人,基本都有实际踩坑经验。这道题能完整回答的,基本都是 P7 水准。
七、面试追问链 🟡
第一层:什么是死锁?
- 候选人:循环等待,无法继续
第二层:死锁的四个必要条件是什么?
- 候选人:互斥、持有并等待、不可抢占、循环等待
第三层:怎么避免死锁?
- 候选人:固定加锁顺序、减少事务时间
第四层:怎么排查死锁?
- 候选人:SHOW ENGINE INNODB STATUS