【MVCC】MVCC之通过readview判断事务读取哪个版本(通俗易懂,一文详解!!)

MVCC的实现原理

mvcc的实现,基于undolog版本链readview。(具体就如下图)

在 MySQL 存储的数据中,MySQL 会默认添加一些额外的隐含字段(Hidden Field),包括 trx_idroll_pointer 等字段。这些字段大多数是用于支持事务和数据恢复等功能。

  • trx_id:是一个系统自动生成的、递增的整数,用于标识当前操作是在哪个事务中执行的。每开始一个新的事务,事务 ID 就会自增 1。因为事务 ID 是系统自动生成的,所以我们一般不需要对其进行手动修改。
  • roll_pointer:是一个指针,用来定位上一个版本的数据。当你对一条记录进行修改时,MySQL 会在内部为该记录创建一份副本并保存到 redo log 中,同时记录下这个副本在 redo log 中的位置,这就是 roll_pointer 所表示的内容。如果发生了回滚操作,MySQL 会通过 roll_pointer 来查找对应记录的上一个版本,并将其恢复回去。

有了这么多的版本之后,当有一个select查询的时候,具体查询的哪个版本呢?

readview读视图来帮我们解决这个问题

当我们用select读取数据时,这一时刻的数据会有很多个版本(例如上图有四个版本),但我们并不知道读取哪个版本,这时就靠readview来对我们进行读取版本的限制,通过readview我们才知道自己能够读取哪个版本

在事务select查询数据时,就会构造一个readview,里面就记录了该条数据版本链的一些统计值,这样在后续查询处理时就无需遍历所有版本链了。

在一个readview快照中具体包括以下这些字段:

对readview中的参数做一些解释

**m_ids:**活跃的事务就是指还没有commit的事务(会像一个集合一样展示出那些活跃【未提交】的事务)。

**max_trx_id:**例如m_ids中的事务id为(1,2,3),那么下一个应该分配的事务id就是4,max_trx_id就是4。

creator_trx_id:当前执行select读这个操作的事务的id。

readview具体判断版本链中的哪个版本可用(重点!)

四步查找规则------

第一步:判断该版本是否由当前事务创建

creator_trx_id=【当前版本trx_id】,意味着读取自己修改的数据,当然可以直接访问。如果不等于当前版本的trx_id则跳到第二步

第二步:【当前版本trx_id】是否小于min_trx_id

【当前版本trx_id】<min_trx_id,说明该版本在生成readview之前已经提交,可以直接访问。如果不是则进行第三步

第三步:【当前版本trx_id】是否大于max_trx_id

【当前版本trx_id】>max_trx_id,说明该版本在生成readview之后才开启,肯定不能被当前事务访问,所以此时就不需要进行第四步再去遍历判断下一个版本。如果当前版本的事务id小于最大事务id则可以继续进行第四步

第四步:min_trx_id<【当前版本trx_id】<max_trx_id

如果当前版本不在活跃事务列表当中,则意味着创建readview的时候,该版本已经被提交,可以直接访问。

如果在活跃事务列表当中,则按照版本链遍历去判断下一个版本,直到找到首个符合要求的版本。

从上到下分别为(1)(2)(3)(4),再依次进行一遍解释,可以加深一遍印象

trx_id表示要读取的事务id

(1)如果要读取的事务id等于进行读操作的事务id,说明是我读取我自己创建的记录,那么为什么不可以呢。

(2)如果要读取的事务id小于最小的活跃事务id,说明要读取的事务已经提交,那么可以读取。

(3)max_trx_id表示生成readview时,分配给下一个事务的id,如果要读取的事务id大于max_trx_id,说明该id已经不在该readview版本链中了,故无法访问。

(4)m_ids中存储的是活跃事务的id,如果要读取的事务id不在活跃列表,那么就可以读取,反之不行。

mvcc如何实现RC和RR的隔离级别

(1)RC 的隔离级别下,每个快照读 都会生成并获取最新的readview

(2)RR 的隔离级别下,只有在同一个事务第一个快照读 才会创建readview ,之后的每次快照读都使用的同一个readview ,所以每次的查询结果都是一样的

相关推荐
DemonAvenger3 分钟前
Redis分布式锁:实现原理深度解析与实战案例分析
数据库·redis·性能优化
m0_7482313124 分钟前
深入JVM:让Java性能起飞的核心原理与优化策略
java·开发语言·jvm
NineData27 分钟前
NineData社区版 V4.6.0 正式发布!SQL 窗口新增4个数据源,新增支持OceanBase等多条数据复制和对比链路
数据库·sql·dba
IT果果日记29 分钟前
给DataX配置加密的方法
大数据·数据库·后端
小白学鸿蒙31 分钟前
鸿蒙数据库表中的数据如何导出为Excel存到系统下载目录
数据库·excel·harmonyos
lang2015092843 分钟前
Spring事务回滚规则深度解析
java·后端·spring
WKP941843 分钟前
mysql的事务、锁以及MVCC
数据库·mysql
命运之光43 分钟前
杀死后台运行的jar程序,并重新运行jar包
java·pycharm·jar
那我掉的头发算什么1 小时前
【数据库】增删改查 高阶(超级详细)保姆级教学
java·数据库·数据仓库·sql·mysql·性能优化·数据库架构
雨夜赶路人1 小时前
SQL -- GROUP BY 基本语法
数据库·sql