首页 >文档 > mysql死锁排查

mysql死锁排查

MySQL死锁排查实战指南:掌握SHOW ENGINE INNODB STATUS分析死锁日志技巧,快速定位循环等待问题。详解索引缺失、事务过大、执行顺序不一致三大死锁根源,提供缩短事务、降低隔离级别、加锁超时等终极解决方案。内含面试应答模板和2025年Java面试宝典资源,助你轻松应对MySQL死锁调优难题。附赠面试鸭会员返利福利,技术提升还能省钱!

mysql死锁排查:程序员实战指南

一、死锁到底是怎么发生的?

想象一个场景:事务A锁定了行1,请求行2;事务B锁定了行2,请求行1——这就是经典的循环等待死锁。MySQL会自动检测死锁并回滚代价较小的事务(通过innodb_deadlock_detect=on),但实际生产环境的死锁往往比这复杂得多。

二、死锁排查三板斧

🔍 1. 抓取死锁日志

直接执行 SHOW ENGINE INNODB STATUS,重点看 LATEST DETECTED DEADLOCK 部分。比如在一次面试中,面试官就让我现场解析这段日志:

*** (1) TRANSACTION:  
TRX_ID 12345, UPDATE table_a SET ... WHERE id=1  
*** (2) TRANSACTION:  
TRX_ID 67890, DELETE FROM table_a WHERE id=2  
*** WE ROLL BACK TRANSACTION (2)

关键信息提取:

  • 冲突的SQL语句(重点关注UPDATE/DELETE/SELECT ... FOR UPDATE)
  • 等待的锁类型(lock_mode X表示排他锁)
  • 持有锁的资源(space id 456 page no 3 指向具体数据页)

🛠 2. 复现死锁场景

根据日志中的SQL,用脚本模拟并发操作。例如:

# 终端1
BEGIN;
UPDATE orders SET amount=100 WHERE user_id=1; -- 锁住user_id=1

# 终端2
BEGIN;
UPDATE orders SET amount=200 WHERE user_id=2; -- 锁住user_id=2
UPDATE orders SET amount=150 WHERE user_id=1; -- 等待终端1的锁

此时在终端1执行 UPDATE ... WHERE user_id=2 就会立刻触发死锁!

📊 3. 分析锁冲突根源

根据我的踩坑经验,90%的死锁由以下原因导致:
| 问题类型 | 典型案例 | 解决方案 |
|------------------|--------------------------|----------------------|
| 索引缺失 | WHERE条件无索引导致锁全表 | 添加联合索引 |
| 事务过大 | 单个事务更新500+行 | 拆分事务+分批提交 |
| 执行顺序不一致| 不同业务代码中UPDATE顺序相反 | 强制统一操作顺序 |

三、终极预防策略

  1. 缩短事务:执行完即时提交,避免跨HTTP请求的事务
  2. 降低隔离级别:用READ COMMITTED代替REPEATABLE READ(需评估业务)
  3. 加锁超时:设置 innodb_lock_wait_timeout=5(单位:秒)
  4. SQL审核:强制要求WHERE条件走索引

💡 插播福利:如果你正在准备面试,推荐使用2025年Java面试宝典(提取码:9b3g),涵盖MySQL调优、分布式锁等高频考点。

四、面试如何优雅回答

当面试官问“实际项目中如何解决死锁?”时,可以这样结构化回答:

  1. 监控:配置报警监听 SHOW STATUS LIKE '%deadlock%'
  2. 取证:通过innodb_print_all_deadlocks=on记录全部死锁日志
  3. 止损:结合APM工具(如SkyWalking)定位热点锁冲突代码
  4. 根治:用EXPLAIN验证索引使用情况,用pt-deadlock-logger自动化分析

🙋 最后打个广告:如果需要开通**面试鸭**会员(原价99元),通过 面试鸭返利网 找我可返现25元!用省下的钱买杯咖啡☕,继续肝代码不香吗?

面试鸭返利网
(扫码或访问 mianshiyafanli.com 获取返利)

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

🎯 立即加入面试鸭会员 →

今日有支付宝大红包赶快领,手慢无

支付宝红包二维码

支付宝扫码领取1-8元无门槛红包

支付宝红包二维码