Java知识分享网 - 轻松学习从此开始!    

Java知识分享网

Java1234官方群25:java1234官方群17
Java1234官方群25:838462530
        
SpringBoot+SpringSecurity+Vue+ElementPlus权限系统实战课程 震撼发布        

最新Java全栈就业实战课程(免费)

springcloud分布式电商秒杀实战课程

IDEA永久激活

66套java实战课程无套路领取

锋哥开始收Java学员啦!

Python学习路线图

锋哥开始收Java学员啦!

mysql 加锁分析 PDF 下载


分享到:
时间:2020-05-19 17:26来源:http://www.java1234.com 作者:小锋  侵权举报
mysql 加锁分析 PDF 下载
失效链接处理
mysql 加锁分析 PDF 下载

本站整理下载:
 
相关截图:
 
主要内容:

4.5 mysql 加锁分析
1.背景
Mysql/innodb的加锁分析,⼀直是⼀个⽐较困难的话题。本⽂,准备就mysql/innoDB的加锁问题,
展开较为深⼊的分析与讨论,主要是介绍⼀种思路,运⽤此思路,拿到任何⼀条SQL语句,就能完
整的分析出这条语句会加什么锁?会有什么样的使⽤风险?甚⾄是分析线上的⼀个死锁场景,了解
死锁产⽣的原因。
注:MySQL是⼀个⽀持插件式存储引擎的数据库系统。本⽂下⾯的所有介绍,都是基于InnoDB存储
引擎,其它引擎的表现,会有较⼤的区别。
1.1 MVCC:Snapshot Read vs Current Read
MySQL InnoDB 存储引擎,实现的是基于多版本的并发控制协议—MVCC(Multi-Version Concurrency Control)
(注:与MVCC 相对的,是基于锁的并发控制,Lock-Based Concurrency Control)。MVCC 最⼤的好处,也是
⽿熟能详:读不加锁,读写不冲突。在读多写少的OLTP 应⽤中,读写不冲突是⾮常重要的,极⼤的增加了系统的
并发性能,这也是为什么现阶段,⼏乎所有的RDBMS,都⽀持MVCC。 在MVCC 并发控制中,读操作可以分为两类:快照读(snapshot read)与当前读(current read)。
快照读,读取的是记录的可见版本(有可能是历史版本),不⽤加锁。当前度,读取的是记录的最新
版本,并且,当前读返回的记录,都会加上锁,保证其他事物不会再并发修改这条记录。
在⼀个⽀持MVCC并发控制的系统中,哪些读操作是快照读?哪些操作又是当前度呢?以MySQL InnoDB为例:
快照读:简单的select 操作,属于快照读,不加锁。(当然,也有例外,下⾯会分析)
当前读:特殊的读操作,插⼊/更新/删除操作,属于当前读,需要加锁。
 select * from table where ? Lock in share mode;
 select * from table where ? For update;
 Insert into table values (…);
 Update table set ? where ?;
 Delete from table where ?;
 所有以上的语句,都属于当前读,读取记录的最新版本。并且,读取之后,还需要保证其他并发事务不能修改
 当前记录,对读取记录加锁。其中,除了第⼀条语句,对读取记录加S锁(共享锁)外,其他的操作,都加的
 X锁(排它锁)
为什么将 插⼊/更新/删除 操作,都归为当前读?可以看看下⾯这个 更新 操作,在数据库中的执⾏流程:
从图中,可以看到,⼀个update操作的具体流程。当update SQL被发给MySQL 后,MySQL Server 会根据where
条件
,读取第⼀条满⾜条件的记录,然后InnoDB 引擎会将第⼀条记录返回,并加锁(current read)。待MySQL收到
这条
加锁的记录之后,会再发起⼀个update 请求,更新这条记录。⼀条记录操作完成,在读取下⼀条记录,直⾄没有
满⾜
条件的记录为⽌。因此,update 操作内部,就包含了⼀个当前读。同理,delete 操作也⼀样,insert操作会稍微有
些不
同,简单来说,就是insert 操作可能会触发Unique Key的冲突检查,也会进⾏⼀个当前读。
注:根据上图的交互,针对⼀条当前读的SQL语句,InnoDB与MySQL Server的交互,是⼀条⼀条进⾏的,因此,
加锁
也是⼀条⼀条进⾏的。先对⼀条满⾜条件的记录加锁,返回给MySQL Server,做⼀些DML操作;然后在读取下⼀
条加
锁,直⾄读取完毕
1.2 Cluster Index:聚簇索引
InnoDB 存储引擎的数据组织⽅式,是聚簇索引表:完整的记录,存储在主键索引中,通过主键索引,就可以获取
记录
所有的列。关于聚簇所以的组织⽅式,可以参考MySQL的官⽅⽂档:clustered and secondary indexes。本⽂假设
者对这个,已经有了⼀定的认识,加不再做具体的介绍。接下来的部分,主键索引/聚集索引 两个名称,会有⼀些
混⽤
,望读者知晓。
1.3 2PL:Two-Phase Locking
传统RDBMS 加锁的⼀个原则,就是2PL(⼆阶段锁):Two-Phase Locking。相对⽽⾔,2PL⽐较容易理解,说的是
锁操
作分为两个阶段:加锁阶段与解锁阶段,并且保证加锁阶段与解锁阶段不相交。下⾯,仍旧以MySQL为例,来简
单看看
2PL 在MySQL中的实现。
从上图可以看出,2PL就是加锁/解锁分为链各个完全不相交的阶段。加锁阶段:只加锁,不放锁。解锁阶段:只
放锁
不加锁。
1.4 Isolation Leve
隔离级别:Isolation Level,也是RDBMS的⼀个关键特性。相信对数据库有所了解的朋友,对于4种隔离级别:
Read Uncommited, Read Commited, Repeatable Read, Serializable,都有了深⼊的认识。本⽂不打算讨论数据库理
论中,
是如何定义这4种隔离级别的含义的,⽽是跟⼤家介绍⼀下 MySQL/InnoDB 是如何定义这4种隔离级别的。
MySQL/InnoDB 定义的4种隔离级别:
 Read Uncommitted
 可以读取未提交记录。此隔离级别,不会使⽤,忽略。
 Read Committed(RC)
 快照读忽略,本⽂不考虑。
 针对当前读,RC隔离级别保证对读取到的记录加锁(记录锁),存在幻读现象。
 Repeatable Read(RR)
 快照读忽略,本⽂不考虑。
 针对当前读,RR隔离级别保证对读取到的记录加锁(记录锁),同时保证对读取的范围加锁,新的满⾜查
 询条件的记录不能够插⼊(间隙锁),不存在幻读现象。
 Serializable
 从MVCC并发控制退化为基于锁的并发控制。部分快照与当前读,所有的读操作均为当前读,读加读锁(S
锁),
 写加写锁(X锁)。
 Serializable 隔离级别下,读写冲突,因此并发度急剧下降,在MySQL/InnoDB 下不建议使⽤。

 

------分隔线----------------------------

锋哥公众号


锋哥微信


关注公众号
【Java资料站】
回复 666
获取 
66套java
从菜鸡到大神
项目实战课程

锋哥推荐