♥️作者:小刘在C站
♥️个人主页: 小刘主页
♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生!
♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术
♥️小刘私信可以随便问,只要会绝不吝啬,感谢CSDN让你我相遇!
前言
上章讲到InnoDB引擎 (中)本章继续,链接这里
目录
4.3 undolog
4.3.1 介绍
4.3.2 版本链
A. 第一步
B.第二步
C. 第三步
4.4 readview
4.5 原理分析
4.5.1 RC隔离级别
A. 先来看第一次快照读具体的读取过程:
B. 再来看第二次快照读具体的读取过程:
4.5.3 RR隔离级别
MySQL
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL 作为网站数据库。
4.3 undolog
4.3.1 介绍
回滚日志,在
insert
、
update
、
delete
的时候产生的便于数据回滚的日志。当
insert
的时候,产生的
undo log
日志只在回滚时需要,在事务提交后,可被立即删除。而
update
、
delete
的时候,产生的
undo log
日志不仅在回滚时需要,在快照读时也需要,不会立即
被删除。
4.3.2 版本链
DB_TRX_ID :
代表最近修改事务
ID
,记录插入这条记录或最后一次修改该记录的事务
ID
,是
自增的。
DB_ROLL_PTR
: 由于这条数据是才插入的,没有被更新过,所以该字段值为
null
。
然后,有四个并发事务同时在访问这张表。
A. 第一步
当事务
2
执行第一条修改语句时,会记录
undo log
日志,记录数据变更之前的样子
;
然后更新记录,
并且记录本次操作的事务
ID
,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。
B.第二步
当事务
3
执行第一条修改语句时,也会记录
undo log
日志,记录数据变更之前的样子
;
然后更新记
录,并且记录本次操作的事务
ID
,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。
C. 第三步
当事务
4
执行第一条修改语句时,也会记录
undo log
日志,记录数据变更之前的样子
;
然后更新记
录,并且记录本次操作的事务
ID
,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。
最终我们发现,不同事务或相同事务对同一条记录进行修改,会导致该记录的
undolog
生成一条
记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。
4.4 readview
ReadView
(读视图)是 快照读
SQL
执行时
MVCC
提取数据的依据,记录并维护系统当前活跃的事务(未提交的)
id
。
ReadView
中包含了四个核心字段:
而在
readview
中就规定了版本链数据的访问规则:
trx_id
代表当前
undolog
版本链对应事务
ID
。
不同的隔离级别,生成
ReadView
的时机不同:
READ COMMITTED
:在事务中每一次执行快照读时生成
ReadView
。
REPEATABLE READ
:仅在事务中第一次执行快照读时生成
ReadView
,后续复用该
ReadView
。
4.5 原理分析
4.5.1 RC隔离级别
RC
隔离级别下,在事务中每一次执行快照读时生成
ReadView
。
我们就来分析事务
5
中,两次快照读读取数据,是如何获取数据的
?
在事务
5
中,查询了两次
id
为
30
的记录,由于隔离级别为
Read Committed
,所以每一次进行快照读
都会生成一个
ReadView
,那么两次生成的
ReadView
如下。
那么这两次快照读在获取数据时,就需要根据所生成的
ReadView
以及
ReadView
的版本链访问规则,到
undolog
版本链中匹配数据,最终决定此次快照读返回的数据。
A. 先来看第一次快照读具体的读取过程:
在进行匹配时,会从undo log的版本链,从上到下进行挨个匹配:
trx_id
为
4
,也就是将
4
带入右侧的匹配规则中。 ①不满足 ②不满足 ③不满足 ④也不满足 ,
都不满足,则继续匹配
undo log
版本链的下一条。
再匹配第三条
,这条记
录对应的
trx_id
为
2
,也就是将
2
带入右侧的匹配规则中。①不满足 ②满足 终止匹配,此次快照
读,返回的数据就是版本链中记录的这条数据。
B. 再来看第二次快照读具体的读取过程:
在进行匹配时,会从undo log的版本链,从上到下进行挨个匹配:
trx_id
为
4
,也就是将
4
带入右侧的匹配规则中。 ①不满足 ②不满足 ③不满足 ④也不满足 ,
都不满足,则继续匹配
undo log
版本链的下一条。
再匹配第二条
,这条
记录对应的
trx_id
为
3
,也就是将
3
带入右侧的匹配规则中。①不满足 ②满足 。终止匹配,此次
快照读,返回的数据就是版本链中记录的这条数据。
4.5.3 RR隔离级别
RR
隔离级别下,仅在事务中第一次执行快照读时生成
ReadView
,后续复用该
ReadView
。 而
RR
是可重复读,在一个事务中,执行两次相同的
select
语句,查询到的结果是一样的。
那
MySQL
是如何做到可重复读的呢
?
我们简单分析一下就知道了
我们看到,在
RR
隔离级别下,只是在事务中第一次快照读时生成
ReadView
,后续都是复用该ReadView
,那么既然
ReadView
都一样,
ReadView
的版本链匹配规则也一样, 那么最终快照读返回的结果也是一样的。
所以呢,
MVCC
的实现原理就是通过
InnoDB
表的隐藏字段、
UndoLog
版本链、
ReadView
来实现的。而
MVCC +
锁,则实现了事务的隔离性。 而一致性则是由
redolog
与
undolog
保证。
♥️关注,就是我创作的动力
♥️点赞,就是对我最大的认可
♥️这里是小刘,励志用心做好每一篇文章,谢谢大家