惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Spread Privacy
Spread Privacy
T
Threatpost
L
LINUX DO - 热门话题
Google Online Security Blog
Google Online Security Blog
I
InfoQ
大猫的无限游戏
大猫的无限游戏
博客园_首页
爱范儿
爱范儿
有赞技术团队
有赞技术团队
V
Visual Studio Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
Jina AI
Jina AI
博客园 - 聂微东
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
CERT Recently Published Vulnerability Notes
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
K
Kaspersky official blog
L
LangChain Blog
G
GRAHAM CLULEY
B
Blog RSS Feed
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
About on SuperTechFans
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
Help Net Security
Help Net Security
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
雷峰网
雷峰网
C
Check Point Blog
MongoDB | Blog
MongoDB | Blog
NISL@THU
NISL@THU
L
Lohrmann on Cybersecurity
Vercel News
Vercel News
T
Tor Project blog
T
The Exploit Database - CXSecurity.com
T
Troy Hunt's Blog
W
WeLiveSecurity
T
Threat Research - Cisco Blogs

博客园 - 郭慕荣

彻底搞懂 Codex Skill 与插件:区别、试用、核心作用、项目落地全指南(程序员实战向) Codex Skill 和插件到底有什么区别?程序员如何在项目中落地使用 claudecode 配置防止配置文件泄露总结 Claude code分析外部文件总结 Claude code三种模式详解 hasCompletedOnboarding详解 Claudecode 有哪些常用的命令 claude.md文件详解 claude code 的setting文件详解 Docker部署zookeeper总结 Mac中git ssh的配置(GitLab) Java 类加载机制 面试题(一) 如何监控和调优JVM性能? jvm常用的参数有哪些? 怎么配置? hashmap 和currenthashmap 的原理?详解一下 aop在项目中使用的场景?怎么使用? Java dubbo spring springboot中的spi机制 spring中常见的两种代理模式 Redis的zset 面试汇总 drools 规则引擎在线化配置 springcloud中常用的注解详解 springcloud中网关gateway总结 spring是怎么解决循环依赖的? 在写left join的时候 是大表在左侧 还是小表在左侧(二) 在写left join的时候 是大表在左侧 还是小表在左侧(一) nacos客户端(接口调用者)如何感知被调用服务下线? (二) nacos客户端(接口调用者)如何感知被调用服务下线?(一) 在MySQL中 redolog undolog binlog 写入的场景,顺序
MySQL 死锁 怎么处理?
郭慕荣 · 2025-10-21 · via 博客园 - 郭慕荣

一、什么是死锁(Deadlock)

定义:

死锁是指两个或多个事务在执行过程中,互相占用资源且等待对方释放,导致事务都无法继续执行的状态。

简单例子:

事务A事务B
UPDATE t1 SET ... WHERE id=1; UPDATE t1 SET ... WHERE id=2;
(锁住 id=1) (锁住 id=2)
UPDATE t1 SET ... WHERE id=2; ← 被事务B锁住 UPDATE t1 SET ... WHERE id=1; ← 被事务A锁住

🔒 这样双方互相等待,InnoDB 检测到死锁后,会自动回滚其中一个事务(通常是锁占用资源少的),释放资源。


二、InnoDB 死锁原理

InnoDB 是 行级锁 + MVCC 的引擎,会使用不同类型的锁:

锁类型说明
共享锁 (S Lock) 允许读取,不允许写入
排他锁 (X Lock) 允许修改,不允许其他事务读/写
意向锁 (IS/IX Lock) 用于协调表锁和行锁
间隙锁 (Gap Lock) 用于防止幻读(在可重复读隔离级别下)

死锁的本质是:

事务之间的锁依赖图中形成了环。


三、死锁检测与分析

1️⃣ 自动检测

MySQL 会自动检测死锁并回滚其中一个事务,返回错误:

2️⃣ 查看死锁日志

执行:

在输出中查找:

你能看到:

  • 哪两个事务冲突;

  • 哪个 SQL 语句导致死锁;

  • 哪个事务被回滚。

👉 生产场景下,死锁分析一般就是从这个日志开始。


四、常见死锁场景

场景说明
1. 更新相同表的不同记录 事务A更新id=1再更新id=2,事务B反过来更新id=2再更新id=1。顺序不一致引发死锁。
2. 唯一索引冲突 + 插入 两个事务插入相同唯一键的记录,InnoDB 会隐式加锁。
3. 间隙锁冲突 可重复读隔离级别下,范围查询 + 插入导致 gap lock 竞争。
4. 外键约束 更新/删除父表、子表数据顺序不一致时,会触发隐式锁定。
5. 大事务 / 批量更新 一个事务锁住大量行,另一个事务锁少量行,可能产生循环等待。

五、死锁的危害

  • ❌ 部分事务会被强制回滚(数据未提交)。

  • ⚠️ 系统性能下降(大量事务等待 / 回滚重试)。

  • 🧨 高频死锁会导致应用报错、事务重试压力增大。

  • 🪣 如果应用层没有正确处理异常(例如直接吞掉异常),可能出现业务逻辑不一致


六、死锁的优化与避免策略

✅ 1. 保证加锁顺序一致

所有业务中操作相同表时,应固定访问顺序。

✅ 2. 尽量缩短事务执行时间

  • 事务只包含必要的 SQL;

  • 不要在事务中长时间等待外部资源(RPC、IO);

  • 提交要及时。

✅ 3. 为查询条件加合适索引

防止锁范围扩大(否则会锁整表或大量记录)。

✅ 4. 减少范围锁(Gap Lock)

  • 使用 READ COMMITTED 隔离级别(可减少间隙锁);

  • 或尽量使用主键/唯一索引精确查询。

✅ 5. 拆分大事务

批量更新、删除操作可以拆分为小批量提交。

✅ 6. 避免并发更新相同行

可以加版本号、状态字段等乐观锁机制(应用层控制)。

✅ 7. 捕获并重试

对死锁异常进行捕获与重试(常用于幂等事务逻辑):


七、面试总结答案(标准化表达)

面试答法:

MySQL 死锁是多个事务之间互相持有并等待对方锁资源而无法继续执行的现象。
InnoDB 会自动检测死锁并回滚其中一个事务。
常见死锁场景包括不同顺序更新同一表、间隙锁冲突、外键约束等。
处理上我们可以通过:

  • 保证加锁顺序一致;

  • 缩短事务时间;

  • 为条件加索引;

  • 使用合适隔离级别(READ COMMITTED);

  • 拆分大事务;

  • 捕获异常并重试;

  • 通过 SHOW ENGINE INNODB STATUS 分析死锁日志。

死锁会导致事务回滚和性能下降,需要重点在设计阶段优化。


八、可执行的排查流程(生产建议)