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

2023-10-11 17:04

本文主要是介绍【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,所以每次的查询结果都是一样的

 

这篇关于【MVCC】MVCC之通过readview判断事务读取哪个版本(通俗易懂,一文详解!!)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/189540

相关文章

Java Lambda表达式的使用详解

《JavaLambda表达式的使用详解》:本文主要介绍JavaLambda表达式的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言二、Lambda表达式概述1. 什么是Lambda表达式?三、Lambda表达式的语法规则1. 无参数的Lambda表

详解如何使用Python构建从数据到文档的自动化工作流

《详解如何使用Python构建从数据到文档的自动化工作流》这篇文章将通过真实工作场景拆解,为大家展示如何用Python构建自动化工作流,让工具代替人力完成这些数字苦力活,感兴趣的小伙伴可以跟随小编一起... 目录一、Excel处理:从数据搬运工到智能分析师二、PDF处理:文档工厂的智能生产线三、邮件自动化:

Spring @RequestMapping 注解及使用技巧详解

《Spring@RequestMapping注解及使用技巧详解》@RequestMapping是SpringMVC中定义请求映射规则的核心注解,用于将HTTP请求映射到Controller处理方法... 目录一、核心作用二、关键参数说明三、快捷组合注解四、动态路径参数(@PathVariable)五、匹配请

git stash命令基本用法详解

《gitstash命令基本用法详解》gitstash是Git中一个非常有用的命令,它可以临时保存当前工作区的修改,让你可以切换到其他分支或者处理其他任务,而不需要提交这些还未完成的修改,这篇文章主要... 目录一、基本用法1. 保存当前修改(包括暂存区和工作区的内容)2. 查看保存了哪些 stash3. 恢

java String.join()方法实例详解

《javaString.join()方法实例详解》String.join()是Java提供的一个实用方法,用于将多个字符串按照指定的分隔符连接成一个字符串,这一方法是Java8中引入的,极大地简化了... 目录bVARxMJava String.join() 方法详解1. 方法定义2. 基本用法2.1 拼接

Java中的record使用详解

《Java中的record使用详解》record是Java14引入的一种新语法(在Java16中成为正式功能),用于定义不可变的数据类,这篇文章给大家介绍Java中的record相关知识,感兴趣的朋友... 目录1. 什么是 record?2. 基本语法3. record 的核心特性4. 使用场景5. 自定

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Python struct.unpack() 用法及常见错误详解

《Pythonstruct.unpack()用法及常见错误详解》struct.unpack()是Python中用于将二进制数据(字节序列)解析为Python数据类型的函数,通常与struct.pa... 目录一、函数语法二、格式字符串详解三、使用示例示例 1:解析整数和浮点数示例 2:解析字符串示例 3:解

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示