【MySQL】MVCC机制

引入问题

首先看下面这张图,假如说一条数据经过了事务 2、3、4,到事务 5 的时候,进行两次查询,那这两次查询分别查询的是哪个事务版本的记录呢?

在这里插入图片描述

这就是我们要解决的问题,那么MVCC机制也就是为了解决这个问题。

具体实现

MVCC 主要依赖三个内容,分别为:隐藏字段undo log 版本链readView

隐藏字段

其实在我们存储数据库中一条数据的时候,并不单单是存储我们看到的那些数据,还会存储一些隐藏字段:最近修改的事务ID、回滚指针roll_pointer等。真实存储如下图所示:
在这里插入图片描述

undo log 版本链

介绍undo log之前,可以先了解一下undo log。

undo log就是回滚日志,我们之前讲到过,在插入、更新、删除的时候会产生便于数据回滚的日志。但是当插入的时候,产生的日志只要在事务提交之后就会立即删除,而更新和删除的时候,产生的日志并不会立即删除的。不仅回滚时需要,MVCC 版本访问的时候也是需要的。

undo log版本链就是把每次修改的undo log以链表形式记录下来,生成的一条版本链表。

在这里插入图片描述

readView

readView 是快照读 SQL 执行时 MVCC 提取数据的依据,记录并维护当前活跃的(未提交的)事务 ID。readView 中有四个字段:

在这里插入图片描述

第一个字段:假如说事务 5 第一次查询,那么当前活跃的事务 ID 就是 3,4,5
第二个字段:最小活跃事务 ID 那就是 3
第三个字段:最大事务是 5,所以预分配事务 id 就是 6
第四个字段:创建者事务 id 就是 5
有了上面那些字段之后呢,为了获取准确的数据,readView 定义了一些数据返回的规则,规则如下:

在这里插入图片描述

有了这些规则之后,我们就可以根据规则来选择合适的版本数据。除此之外,我们需要知道不同隔离级别下,生成的读视图(readView )时机是不同的。

例如 RC 在事务中每一次执行快照读生成readView;RR 仅在事务第一次执行快照读生成readView,后续复用上面的readView

下面简单举例,RC 级别下生成的 readView:

在这里插入图片描述

再结合规则我们来进行判断看选择哪一次 undo log 链中的事务来进行读:

在这里插入图片描述

比如第一个 4 来进行判断,① 条件不满足,② 条件不满足,③ 条件不满足,④ 条件也不满足,所以说事务 4 是不选择的
接着 3,①,② ,③ ,④ 条件也都不满足,所以事务 3 不选择
看事务 2,① 条件不满足,但是② 就满足了,也满足 ④,所以读的就是事务 2 中的数据
因为是 RC 级别下,所以第二次查询又生成了一个 readView,根据上面规则,很容易就能选择到事务 3 满足条件

RR 级别下生成 readView:
在这里插入图片描述

总结

MVCC 机制主要是包括三大部分:隐藏字段undo log 版本链readView

我们存储的数据会默认也存储两个隐藏字段,分别为当前修改的事务 id 和 roll_pointer 回滚指针

undo log 是回滚日志,存储老版本的数据。多个事务操作某一行数据,记录不同事务修改数据的版本,通过回滚指针形成的链表叫做 undo log 版本链

readView 解决了事务查询选择版本的问题,根据 readView 的匹配规则和当前事务 id 判断该访问哪个版本的数据。不同隔离级别 readView 是不一样的,最终访问结果也是不同的。比如 RC,每一次执行快照读生成 readView,RR 仅在事务第一次执行快照读时生成 readView,后续复用

参考链接

https://www.bilibili.com/video/BV1yT411H7YK?p=32&vd_source=8e7bfe48e222037c101ebbfa23645009

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值