从ReadView深入理解MySql MVCC原理

MySql MVCC 机制

在说MVCC机制前我们先了解ReadView。

ReadView是什么呢?在我们平时执行一个事务的时候,就会生成一个ReadView,ReadView的组成结构大致如下
在这里插入图片描述

参数说明:

  1. creator_trx_id:当前事务id
  2. m_ids:所有事务的事务id
  3. min_trx_id:m_ids里最小的事务id值
  4. max_trx_id:最大事务id

我们来具体分析一下ReadView的作用,以及是如何解决脏读幻读,不可重复读的问题的

现在数据有一条数据,如下原始值,上一个已经提交事务的事务txr_id=30

在这里插入图片描述

此时两个事务并发执行, 事务A(txr_id= 40),事务B(txr_id=50),事务A要读取这行数据,事务B要更新这行数据。

此时事务A在读取时开启ReadView,此时的ReadView的值如下:

m_ids:=[40,50]

min_trx_id=40

max_trx_id=51

creator_trx_id=40

事务A在第一次查询发起一个判断,判断当前数据的txr_id是否小于ReadView中的min_trx_id(此时txr_id (30)< min_trx_id(40)),说明在A事务开启前,修改这行数据的事务已经提交了,所以可以查询这条数据

在这里插入图片描述

接着事务B开始修改数据为B值,然后将这行数据的txr_id设置为自己的txr_id(50),然后将roll_pointer指向之修改前生成的undo log备份,然后提交事务

在这里插入图片描述

此时A再重复查询,当读取B修改的数据时,发现在ReadView中min_txr_id(40)<txr_id(50)<max_trx_id(51),同时txr_id=50在m_ids,可以确定修改数据的事务和自己处于同一时间并发提交的,为了保证可重复读,这行数据是不能查询的,所以需要通过roll_pointer顺着undo log链表找到最近的一条undo log,即修改前的值,找到txr_id = 30(B未修改的值) 发现此时原始值的 txr_id < min_trx_id,说明这条数据肯定是在事务A开启钱前提交的,所以可以查询,就查询txr_id=30的值,即查询的的还是原始的值,这样就保证了可重复读

如果此时的数据隔离级别是Read committed,即B事务一旦提交,A下次查询就可以马上查询到事务B提交的值了,ReadView是如何做到这一点的呢?
那就是每次事务A查询时都新生成ReadView,来看看在事务B提交后A重新查询后生成的ReadView是什么样的
在这里插入图片描述
这次A重复查询在ReadView中 min_txr_id(40)<txr_id(50)<max_trx_id(41),但是事务B的事务id不在m_ids中,说明事务B虽然和自己同一时间开启,但是已经提交了事务,所以可以查询B修改的数据即txr_id = 50的值

接着事务A再更新这行数据,此时这行数据的trx_id=40,此时数据如下

在这里插入图片描述

此时事务A重新查询,发现txr_id=40 = creator_trx_id,说明这条数据就是自己修改的,也是可以读取到,所以就读取到

如果此时再开启一个事务C,事务id=60,更新这行数据

在这里插入图片描述

如果A再次查询会发现trx_id=60 > max_trx_id(id=51),说明事务C是事务A开启后开启的,自己也是不能读取到,所以也是顺着undo log向下找到 txr_id = 40 读取到值

同理如果事务隔离级别是 Repeatable read,C事务插入一条数据也是如此,A是读取不到的,从而也解决了幻读问题

关于我

觉得文章不错请扫码关注我吧

weichat

  • 14
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值