如何理解mysql的mvcc

## 问:如何理解mysql的mvcc

所谓多版本,就是一行记录在数据库中存储了多个版本(版本链),每个版本以事务ID作为版本号。InnoDB 引擎表中,它的聚簇索引记录中有两个必要的隐藏列: trx_id  这个id用来存储的每次对某条聚簇索引记录进行修改的时候的事务id,roll_pointer  就是存了一个指针,它指向这条聚簇索引记录的上一个版本的位置,通过它来获得上一个版本的记录信息。每次查询在事务开始的时候向InnoDB的事务系统申请trx_id,并且按照申请顺序严格递增的。假如一行记录被多个事务更新,那么,就会产生多个版本的记录。注意插入操作的undo日志(版本链)没有这个属性,因为它没有老版本)

举个例子:版本链如下图

ReadView

注意与view的区分,通过语法create view … 实现,主要创建一个虚拟表,用来执行查询语句。
ReadView是InnoDB用来实现mvcc的一致性视图(consistent read view),纯逻辑概念,没有物理结构,主要是支持InnoDB在“读已提交”和“可重复读”级别的并发访问问题。ReadView存储我们系统中当前活跃着的读写事务,也就是begin了还未提交的事务。通过这个列表来判断记录的某个版本是否对当前事务可见。

不同的事务隔离级别创建   ReadView 的策略不一样:

 “读未提及”级别下,没有一致性视图
     “读已提交”级别下,会在 每个SQL开始执行的时候 创建一致性视图
     “可重复读”级别下,会在 每个事务开始的时候 创建一致性视图
     “串行化”级别下,直接通过加锁避免并发问题

假设当前的ReadView事务id为[80,100]

     如果你要访问的记录版本的事务小于80,那说明这个事务在之前就提交了,所以对当前活动的事务来说是可见的。

     如果你要访问的记录版本的事务id为90,发现此事务在列表id最大值和最小值之间,那就再判断一下是否在列表内,如果在那就说明此事务还未提交,所以版本不能被访问。如果不在那说明事务已经提交,所以版本可以被访问。

     如果你要访问的记录版本的事务id为110,那比事务列表最大id100都大,那说明这个版本是在ReadView生成之后才发生的,所以不能被访问。这些记录都是去版本链里面找的,先找最近记录,如果最近这一条记录事务id不符合条件,不可见的话,再去找上一个版本再比较当前事务的id和这个版本事务id看能不能访问,以此类推直到返回可见的版本或者结束。

举个例子 ,在已提交读隔离级别下:

比如此时有一个事务id为100的事务,修改了name,使得的name等于小明2,但是事务还没提交。则此时的版本链是

那此时另一个事务发起了select 语句要查询id为1的记录,那此时生成的ReadView 列表只有[100]。那就去版本链去找了,首先肯定找最近的一条,发现trx_id是100,也就是name为小明2的那条记录,发现在列表内,所以不能访问。

这时候就通过指针继续找下一条,name为小明1的记录,发现trx_id是60,小于列表中的最小id,所以可以访问,直接访问结果为小明1。

那这时候我们把事务id为100的事务提交了,并且新建了一个事务id为110也修改id为1的记录,并且不提交事务

这时候版本链就是

这时候之前那个select事务又执行了一次查询,要查询id为1的记录。

这个时候关键的地方来了

如果你是已提交读隔离级别,这时候你会重新生成一个ReadView,那你的活动事务列表中的值就变了,变成了[110]。

按照上的说法,你去版本链通过trx_id对比查找到合适的结果就是小明2。

如果你是可重复读隔离级别,这时候你的ReadView还是第一次select时候生成的ReadView,也就是列表的值还是[100]。所以select的结果是小明1。所以第二次select结果和第一次一样,所以叫可重复读!

也就是说已提交读隔离级别下的事务在每次查询的开始都会生成一个独立的ReadView,而可重复读隔离级别则在第一次读的时候生成一个ReadView,之后的读都复用之前的ReadView。

这就是Mysql的MVCC,通过版本链,实现多版本,可并发读-写,写-读。通过ReadView生成策略的不同实现不同的隔离级别。

 

参考博客:https://blog.csdn.net/belalds/article/details/98759840

                  https://blog.csdn.net/u014730658/article/details/105133990

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值