MySQL数据库MVCC机制底层原理详解

mvcc机制即多版本并发控制

当在事务中使用了写操作(增删改)语句时会给当前事务生成一个事务id,事务id是递增的

同时,对于被修改的行的数据会创建一个数据版本 ,这个数据版本除了包含原有的字段还会包含一个事务id和一个回滚指针

接下来通过几条sql语句来讲解mvcc机制:

首先假设这里有一个account表,此时里面只有一条数据

 

trx_id:事务id

roll_pointer:回滚指针 

假设上面的4个事务都已经开启了,现在执行3行和4行,由于是写操作,所以会生成一个事务id,这里我们假设是110 和 120,注意此处操作的不是account表,只是为了生成事务id。

接下来执行第5行,同样是一个写操作也会生成事务id,同时上面我们说过,对于被修改的数据行还会生成一个数据版本,于是这个新生成的数据版本就是当前数据行最新的版本,它的回滚指针会指向上一个版本:

紧接着事务130就提交了,然后另一个事务指向了一个查询语句,这里大家应该都知道结果是ting130,因为事务130提交了。注意查询语句不会生成事务id

此时继续往下执行,8和9行,同样是更新语句所以也会生成数据版本,注意每个事务中只有第一次执行写操作语句时会生成事务id。

此时第10行执行一个查询语句,我们分析一下此时的查询结果是什么:

当事务中第一次执行查询操作时,会生成一致性视图 read -view,也可以称为快照,他由当前未提交事务id组成的数组和已创建的最大事务id(max_id)组成,其中未提交事务id中最小的id我们称为min_id,通过min_id和max_id可以把事务分为三个部分:

由于min_id是所有未提交事务中最小的id,所以事务id小于min_id的一定是已经提交的事务是可见的,同时大于max_id的事务,是生成快照时还没有创建的事务,是不可见的,在min_id和max_id之间的事务要分两种情况,在未提交数组中则说明是不可见的,不在则说明事务已经提交是可见的,当执行查询语句,就会沿着版本链从最新的数据开始查,直到查到可见的数据。

所以第7行时,第四个事务就已经生成了快照,当时只有事务130提交了,所以生成的read_view是:[ 110 , 120 ] 130 ,110即为min_id,130为max_id,由于同一个事务中只有第一次使用查询语句时会生成read_view,所以此时第10行的查询语句会沿用上次的read_view即 [ 110 , 120 ] 130

此时我们沿着版本链去查数据,首先查到的是ting112,发现事务id在未提交事务数组中说明不可见,沿着回滚指针往下找到ting111发现同样不可见,继续往下找到ting130,事务id为130 ,130 小于等于max_id并且不在未提交事务数组中,是可见的,于是返回ting130。

接下来继续往下执行,到第14行的时候,又将执行一条查询语句,可以先不看下面自己试着梳理一下返回什么。

此时版本链中又多了两条数据:

我们同样按照read_view在版本链中找,注意,这里不会生成新的read_view会沿用上次生成的

[ 110 , 120 ] 130

首先找到ting122,ting121发现事务id为120不可见,继续往下找到ting112,ting111 事务id为110同样不可见,在往下找到ting130事务id为130是可见的,所以返回ting130

再做个练习:

此时第14行的查询语句会返回什么? 

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ting-yu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值