MySQL 加锁和死锁解析
目录
产生死锁的必要条件
- 多个并发事务(2个或者以上)
- 每个事物都持有了锁(或者是已经在等待锁)
- 每个事务都需要再继续持有锁(为了完成事务逻辑,还必须更新更多的行)
事物之间产生加锁的循环等待,形成死锁
常规锁模式
- LOCK_S(读锁,共享锁)
LOCK_X(写锁,排它锁)
锁的属性
- LOCK _REC_NOT_GAP(锁记录)
- LOCK_GAP(锁记录前的GAP)
- LOCK_ORDINARY(同时锁记录+记录前的GAP,Next key锁)
LOCK_INSERT_INTETION(插入意向锁)
锁组合(属性+模式)
可以任意组合
锁冲突矩阵

锁是加在那里的?
根据主键查找-锁加在主键上
如 begin;select * from tt_copy where id=4 for update;
加锁情况index PRIMARY of table
test.tt_copytrx id 1101588 lock_mode X locks rec but not gap
根据普通索引查找-锁加在普通索引和主键上
如 begin;select * from tt_copy force index(idx_a) where a=4 for update;
加锁情况index idx_a of table
test.tt_copytrx id 1101590 lock_mode X locks rec but not gap
index PRIMARY of tabletest.tt_copytrx id 1101590 lock_mode X locks rec but not gap
操作与加锁的对照关系
以下没特殊说明都为RC隔离级别
Insert
- 无Unique key,插入后 :无论RC或RR隔离级别都是对主键加 LOCK_X+LOCK_REC_NOT_GAP
有Unique key
插入前,唯一约束检查:LOCK_S+LOCK_ORDINARY
插入前,插入的位置有GAP锁:LOCK_INSERT_INTETION
插入后,新数据插入:LOCK_X+LOCK_REC_NOT_GAP
Delete
满足删除条件的所有记录:LOCK_X+LOCK_REC_NOT_GAP
Update
Update操作分解
- Step 1:定位到 下一条满足查询条件的记录(查询过程,类似于Select/Delete)
- Step 2:删除当前定位到的记录(标记为删除状态)
- Step 3:拼装更新后项,根据更新后项定位到 新的插入位置
- Step 4:在新的插入位置,判断是否存在 Unique 冲突( 存在Unique Key 时)
- Step 5:插入更新后项(不存在Unique冲突时)
- Step 6: 重复Step 1 到Step 5 的操作,直至扫描完整个查询范围
Update操作分析
- Step 1,Step 2:Delete
- Step 3,Step 4,Step 5:Insert
Update
无Unique key:
- 查询范围中的所有记录,LOCK_X + LOCK_REC_NOT_GAP
有Unique key:
- 查找满足条件的记录:查询范围内的所有记录, LOCK_X + LOCK_REC_NOT_GAP
- 更新后项存在唯一性冲突:冲突项上的加锁,LOCK_S + LOCK_ORDINARY
- 更新后项不存在唯一性冲突: 更新位置后项加锁,LOCK_S + LOCK_GAP (省略)
- 实际更新操作:可看做插入了一条新纪录,LOCK_X + LOCK_REC_NOT_GAP
GAP锁
那些操作会加GAP锁?
- Read Committed (RC) ) :Unique Key 唯一约束检查;Purge操作;
- Repeatable Read (RC ):RC的基础上,所有需要加锁的索引范围扫描和索引查找(Update/Delete…)
- 还有一种会加GAP锁:RR隔离级别下,对有唯一索引的表执行insert on duplicate update操作,除了会对新插入的记录加x not gap外,还会对相邻记录加x gap
如何去掉GAP锁?
change the transaction isolation level to READ COMMITTED or enable the innodb_locks_unsafe_for_binlog system variable (which is now deprecated)
什么时候加next-key lock?
By default, InnoDB operates in REPEATABLE READ transaction isolation level. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows
Insert Intention Lock
An insert intention lock is a type of gap lock set by INSERT operations prior to(在...之前) row insertion.
总结
• 原则之一
- 要分析一个死锁,必须深入业务,了解整个事务的逻辑(闭门无法造车)
• 原则之二`
- GAP锁很复杂,为了减少GAP锁,减少GAP导致的死锁,尽量选择Read Committed隔离级别(RC + row based binlog,基本上能够解决所有问题,无需使用Repeatable Read)
- 适当的 减少Unique 索引,能够减少GAP锁导致的死锁(根据业务情况而定)
• 原则之三
- 在MySQL 中,以不同索引的过滤条件, 来操作相同的记录(Update/Delete ),很容易产生死
锁。
• 原则之四
- RC隔离级别下,如果死锁中出现Next Key(Gap锁),说明表中一定存在unique索引
- 多语句事务产生的死锁,确保每条语句操作记录的顺序性,能够极大减少死锁
本文大多数都整理自《死锁-何登成 - 管中窥豹——MySQL(InnoDB)死锁分析之道》
MySQL 加锁和死锁解析的更多相关文章
- Mysql加锁过程详解
1.背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文, ...
- MySQL 加锁处理分析
1 背景 1 1.1 MVCC:Snapshot Read vs Current Read 2 1.2 Cluster Index:聚簇索引 3 1.3 2P ...
- MySQL 加锁处理分析 转
MySQL 加锁处理分析 转 http://hedengcheng.com/?p=771 十二 13th, 2013 发表评论 | Trackback 1 背景 1 1.1 M ...
- 转载-MySQL 加锁处理分析
MySQL 加锁处理分析 发表于 2013 年 12 月 13 日 由 hedengcheng 1 背景 1 1.1 MVCC:Snapshot Read vs Current Re ...
- MySQL加锁分析
参考:MySQL 加锁处理分析.该文已经讲的很详尽了,也易懂,下面仅仅是个人做的总结. 一. 背景 1.1 隔离级别 1.2 加锁过程 逐条处理,逐条加锁. 1.3 两阶段锁2PL 1.4 gap锁 ...
- MySQL 加锁处理分析-转载
来自何登成的技术博客 1.1 MVCC:Snapshot Read vs Current Read 2 1.2 Cluster Index:聚簇索引 3 1.3 ...
- Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock)
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Mysql加锁过程详解(1)-基本知识
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
随机推荐
- 牛客CSP-S提高组赛前集训营2 ———— 2019.10.31
比赛链接 期望得分:100+20+20 实际得分:40+20+30 awa cccc T1 :基于贪心的思路,然后开始爆搜(雾 那必然是会死的,好吧他就是死了 #include<iostrea ...
- vijos2051 SDOI2019 快速查询
题目链接 吐槽 竟然让\(nlog\)的做法卡过去了.. 思路 因为\(1 \le q \le 10^5\),所以可以先对每个标准操作,所操作的位置进行重标号.这样所有的下标都是在\(10^5\)以内 ...
- 【2019.7.26 NOIP模拟赛 T1】数字查找(figure)(数学)
推式子 我们设\(n=kp+w\),则: \[(kp+w)a^{kp+w}\equiv b(mod\ p)\] 将系数中的\(kp+w\)向\(p\)取模,指数中的\(kp+w\)根据欧拉定理向\(p ...
- MySQL实战45讲学习笔记:第二十三讲
一.本节概要 今天这篇文章,我会继续和你介绍在业务高峰期临时提升性能的方法.从文章标题“MySQL 是怎么保证数据不丢的?”,你就可以看出来,今天我和你介绍的方法,跟数据的可靠性有关. 在专栏前面文章 ...
- Apollo:微服务架构下的配置管理
问题背景 在实际工作中,我们的开发环境,测试环境,生产环境对应的 Mysql 数据库,Redis 这些信息都不一样,每个环境都有对应的一套配置,在 Spring Boot 中我们通常会编写多个配置文件 ...
- DVWA XSS (Stored) 通关教程
Stored Cross Site Scripting 存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户 ...
- java ++和--
public class Sample { public static void main(String[] args) { , num2 = ; , num4 = ; System.out.prin ...
- python运维开发常用模块(四)文件对比模块difflib
1.difflib介绍 difflib作为 Python的标准库模块,无需安装,作用是对比文本之间的差异,且支持 输出可读性比较强的HTML文档,与Linux下的diff命令相似.我们可以 使用dif ...
- WPF XAML的读法
XAML 一直以为读作X-A-M-L 不过 一直都是念错了 正确念法:ZAMMEL 类似:ZeIMO [平音]
- Filebeat与Logstash配置SSL加密通信
为了保证应用日志数据的传输安全,我们可以使用SSL相互身份验证来保护Filebeat和Logstash之间的连接. 这可以确保Filebeat仅将加密数据发送到受信任的Logstash服务器,并确保L ...