【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 ,所以每次的查询结果都是一样的

相关推荐
吴声子夜歌2 分钟前
SQL经典实例——插入、更新和删除
数据库·sql
基德爆肝c语言5 分钟前
MySQL:数据库基础
数据库·mysql
倒流时光三十年6 分钟前
PostgreSQL GREATEST 条件表达式函数详解
服务器·数据库·postgresql
Javatutouhouduan7 分钟前
2026年Java面试核心讲(终极版)全网首次开源!
java·jvm·java多线程·java面试·后端开发·java程序员·java八股文
山峰哥10 分钟前
VBA数据结构之争:Dictionary vs Collection,性能差3倍!
服务器·数据结构·数据库·windows·sql·算法·哈希算法
摇滚侠12 分钟前
MyBatis 入门到项目实战 MyBatis 各种查询功能 30-33
java·后端·spring·maven·intellij-idea·mybatis
兰令水2 小时前
leecodecode【面试150】【2026.6.14打卡-java版本】
java·算法·面试
yaoxin5211238 小时前
434. Java 日期时间 API - Period 基于日期的时间段
java·开发语言·python
何极光9 小时前
IDEA集成Maven
java·maven·intellij-idea
火山上的企鹅10 小时前
Codex实战:APP远程升级服务搭建(三)后台管理页面(APK 上传、版本管理、多应用页签)
服务器·网络·数据库·oracle·qgc