MySQL MVCC工作原理

news2024/11/18 21:37:37

        之前的文章中我们讲到,MySQL事务的隔离级别有四种分别是:read uncommitted、read committed、repeatable read和serializable。现在InnoDB下默认的存储引擎是repeatable read,之前也提过在repeatable read下MySQL是通过MVCC来解决幻读的问题。本文就介绍一下MVCC的原理。

      MVCC定义

         MVCC(Multi-Version Concurrency Control),叫多版本并发控制,它是一个抽象概念而非具体实现,它通过给每行数据维护了一个版本链条控制,从而实现非阻塞的并发读。

      MVCC原理

        要了解MVCC原理需要先了解当前读快照读的区别,还有undolog的作用,以及了解readview的结构。MVCC实现原理主要是依赖每行数据中记录了 3个隐式字段(DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR),undo日志 ,Read View 来实现的。

       当前读和快照读

        当前读:事务在修改该数据或对该数据加锁时这时的读就是当前读,它读取的是最新的版本数据,同时在读取时会对该记录加锁防止其他事务进行修改。因此对update、delete、select for update、select lock in share mode 这些操作都是当前读。

        快照读:它是一种不加锁的非阻塞读,它的前提不能是串行的隔离级别。它在读取时不会进行加锁操作,其他事务可能会对该记录进行修改,所以它读取的数据不一定是最新的版本数据。这种做法是为了提高并发读的性能。

        undolog

        记录了当前事务修改记录的反操作记录,在事务中用于做回滚操作,它记录了不同事务对同一行记录修改的版本链条。

       

        undolog 分为insert undolog和update undolog。

        insert undo log是指在insert操作中产生的undo log。由于insert操作的记录,只是对本事务可见,其他事务不可见,所以undo log可以在事务提交后直接删除,而不需要purge操作。

        update undo log是指在delete和update操作中产生的undo log。该undo log会被后续用于MVCC当中,因此不能提交的时候删除。提交后会放入undo log的链表,等待purge线程进行最后的删除

        3个隐式字段

        DB_ROW_ID:隐藏的主键如果没有设置主键则会自动生成。目前我们基本都会自己设置主键就不用这个字段。

        DB_TRX_ID:这是一个事务的全局变量,记录了该数据最新修改的事务ID。

        DB_ROLL_PTR:回滚指针,指向该行记录的上一个版本的地址,其指向的就是undo log的位置。

        Read View

        Read View 就是事务进行快照读操作的时候生产的读视图 (Read View)。事务中对其他事务操作的可见性就是Read View来做的可见性判断。
        Read View的记录了以下几个值:trx_list (当前活跃事务列表)、min_trx_id(活跃事务中最小事务ID)、max_trx_id(当前未分配的下一个事务ID)、creator_trx_id(快照读的当前事务ID)。

        事务ID生成规则

        当一个事务开启的时候,并不会立刻生成事务id ,而是执行增删改的时候才会生成 id ,事务id=最大事务ID+1,同一个事务内的所有修改事务ID一致。

        当开启一个事务它的第一次执行动作时快照读时会给该事务生成一个很大的数,这个数的生成算法是把当前事务的 trx变量的指针地址转成整数再加上 2,这个事务ID是一个临时的事务ID,不会被记录在全局的trx_id中。

        可见性判断算法

        1. DB_TRX_ID = creator_trx_id 如果成立则证明该事务修改在本事务中所以是可见的。

        2.DB_TRX_ID<min_trx_id如果成立则能证明是在快照读时已经提交的事务是可以看到DB_TRX_ID的记录,不成立则进入下一步判断。

        3. DB_TRX_ID>=max_trx_id如果成立则代表DB_TRX_ID的记录是在快照读生成后才出现,所以是看不到该事务记录,如果小于则进入下一步判断。

        4. 判断DB_TRX_ID in (trx_list) 如果在则说明快照读时该事务还在活跃中还未提交,因此是不可见的,如果不在则说明该事务已经提交了,那么对当前事务是可见的。

        当前DB_TRX_ID如果是不可见的则会根据undolog版本链条中找到前一条事务ID进行判断直到找到可见的那个版本数据。

        可见性判断的模拟

时间事务A事务B事务C事务D事务E
T1beginbeginbegin
T2update
trx_id = 1
commit
update
trx_id=2
beginbegin
T3select1update
trx_id=3
T4commitselect2
T5commitupdate
trx_id=4
T6select3
T7select4commit

        上图中有5个事务在进行中,在7个时间节点里进行了不同的操作,这里记录下了每次快照读时的事务变化。

T3时间节点select1进行可见性判断:

此时DB_TRX_ID=3

1. 判断creator_trx_id = DB_TRX_ID,发现不相等,证明该记录修改并非本事务的修改。进入下一步判断。

2. DB_TRX_ID<min_trx_id, 3<2不成立,证明该快照读产生时事务还未提交,所以不可见,进入下一步判断。

3. DB_TRX_ID>=max_trx_id,3>=4不成立 ,所以进入下一步判断。
4. 判断DB_TRX_ID in (trx_list) ,3 in (2,3) 说明生成快照读时该事务还在活跃中还未提交,因此是不可见的。

所以判断事务ID=3的记录对当前快照读不可见。

这时需要从undo log中去找下一个事务ID也就是 DB_TRX_ID=2,同样进行以上4个判断,发现也不可见。

再次继续找DB_TRX_ID=1进行判断,发现DB_TRX_ID=1,命中了条件2所以对1是可见的。因此查询出来的结果就是事务ID=1时修改结果。

T4时间节点select2进行可见性判断:

此时DB_TRX_ID=3

1. 判断creator_trx_id = DB_TRX_ID,发现不相等,证明该记录修改并非本事务的修改。进入下一步判断。

2. DB_TRX_ID<min_trx_id, 3<3不成立,证明该快照读产生时事务还未提交,所以不可见,进入下一步判断。

3. DB_TRX_ID>=max_trx_id,3>=4不成立 ,所以进入下一步判断。
4. 判断DB_TRX_ID in (trx_list) ,3 in (3) 说明生成快照读时该事务还在活跃中还未提交,因此是不可见的。

这时需要从undo log中去找下一个事务ID也就是 DB_TRX_ID=2,同样进行以上4个判断,发现命中了条件2,因此该快照读对DB_TRX_ID=2的记录时可见的。

T6时间节点select3进行可见性判断:

此时DB_TRX_ID=4,由于RR级别下readview 在第一次快照读就生成了所以下一次快照读时复制原readview 因此该快照读时的 tax_list、min_trx_id、max_trx_id这几个信息和T4是一致的。

1. 判断creator_trx_id = DB_TRX_ID, 4=4 成立则说明该记录是本事务修改的,因此是可见的。

T7时间节点select4进行可见性判断:

        此时DB_TRX_ID=4,由于RR级别下readview 在第一次快照读就生成了所以下一次快照读时复制原readview,因此该快照读时的 tax_list、min_trx_id、max_trx_id 这几个信息和T3是一致的。 最后进行判断发现其可见性和T3时刻的可见性也是一致的。

        总结
       

        MySQL MVCC的工作原理是依靠快照读生成Read View记录下当前活跃的事务ID,同时在本事务修改时也会将本事务的creator_trx_id记录在Read View中。最后通过和全局变量中的DB_TRX_ID进行比较判断其可见,如果当前事务ID不可见就从undo log中找到其上一次修改的记录再次进行判断直到找到满足条件的记录。

        RR隔离级别和RC隔离级别在快照读时生成Read View是不一样的,RC在每次快照读时都会生成新的Read View 因此它在同一事务中是可以读到其他事务修改并提交的记录。RR隔离级别在同一事务中只会在第一次快照读时生成Read View,第二次的快照读都是复制了第一次的Read View数据进行判断,因此它在两次读取的结果时一致的。

        MVCC也只是很大程度上解决幻读的问题,并不会完全的解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/29694.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Dubbo服务调用扩展点Filter的介绍与使用

扩展点介绍 如上图所示&#xff0c;从服务调用的角度来看&#xff0c;Dubbo 在链路中提供了丰富的扩展点&#xff0c;覆盖了负载均衡方式、选址前后的拦截器、服务端处理拦截器等。 简单来说 Dubbo 发起远程调用的时候&#xff0c;主要工作流程可以分为消费端和服务端两个部分。…

Linux网络--------http协议

文章目录URL---网址对http协议的宏观认识http协议的请求方法http响应的状态码最简单的http协议服务器关于http协议的一些概念性知识URL—网址 首先&#xff0c;http协议是应用层协议&#xff0c; 是超文本传输协议。 urlencode : 转码 urldecode &#xff1a; 解码 将 ---- …

python自学入门(打卡十)2022-11-22

Pytest与Unittest区别 参考资料&#xff1a;https://blog.csdn.net/qq_33385691/article/details/112004487 pytest用例规则 文件名以test_.py文件和test.py 以test_开头的函数 以Test开头的类&#xff0c;test_开头的方法&#xff0c;并且不能带有__init_ 方法 所有的包pake…

极智AI | 昇腾开发环境搭建 CANN MindStudio (无坑版)

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多笔记分享 大家好&#xff0c;我是极智视界&#xff0c;本文介绍一下 昇腾开发环境搭建 CANN & MindStudio&#xff0c;没有坑。 本文介绍的方法适用于&#xff1a; 系统&#xff1a;ubuntu18.04 (注&#xff1a;[ce…

5个常见的JavaScript内存错误

JavaScript 不提供任何内存管理操作。相反&#xff0c;内存由 JavaScript VM 通过内存回收过程管理&#xff0c;该过程称为垃圾收集。 既然我们不能强制的垃圾回收&#xff0c;那我们怎么知道它能正常工作&#xff1f;我们对它又了解多少呢&#xff1f; 脚本执行在此过程中暂停…

计算机毕业设计之java+ssm某地区精准扶贫网站

项目介绍 本精准扶贫网站管理系统主要包括系统用户管理模块、捐赠信息管理模块、投诉信息管理、扶贫资讯管理、登录模块、和退出模块等多个模块,系统采用了jsp的mvc框架,SSM(springMvcspringMybatis)框架进行开发,本系统使用mysql&#xff0c;独立运行,不依附于其他系统&#…

Redis数据类型之set

文章目录setⅠ. 基础操作Ⅱ. 随机数据Ⅲ. 交、并、差Ⅳ. 应用场景Ⅴ. 注意事项提示&#xff1a;以下是本篇文章正文内容&#xff0c;Redis系列学习将会持续更新 set ● 数据存储需求&#xff1a;存储大量的数据&#xff0c;在查询方面提供更高的效率。 ● 需要的存储结构&#…

家乡主题网页设计代码 旅游主题网页设计 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

详细解读Spring Boot中@Import三种使用方式

需要注意的是&#xff1a;ImportSelector、ImportBeanDefinitionRegistrar这两个接口都必须依赖于Import一起使用&#xff0c;而Import可以单独使用。Import是一个非常有用的注解&#xff0c;它的长处在于你可以通过配置来控制是否注入该Bean&#xff0c;也可以通过条件来控制注…

CNN卷积神经网络

&#xff08;声明&#xff1a;本文章是在学习他人视频的学习笔记&#xff0c;图片出处均来自该up主&#xff0c;侵权删 up主链接&#xff1a;同济子豪兄的个人空间_哔哩哔哩_bilibili&#xff09; 卷积神经网络就像一个黑箱&#xff0c;有输入和输出&#xff0c;输入是一个图像…

Spring 中更加简单的 “存储“ 和 “读取“ 对象

目录 1. 更加简单的存储对象 1.1 配置扫描路径 1.2 使用五大类注解存储 bean 对象 1.2.1 五大类注解之间的关系 1.2.2 关于 bean 的命名规则 1.3 使用方法注解存储 bean 对象 1.3.1 bean 的重命名 2. 更加简单的获取对象 (DI) 2.1 属性注入 2.1.1 属性注入优缺点分析 …

三、图片的几何变换

目录一、图片缩放1 - 等比缩放2 - 最近领域插值3 - 双线性插值4 - 矩阵缩放二、图片剪切与位移1 - 图片剪切2 - 图片位移三、图片镜像四、图片仿射变换五、图片旋转一、图片缩放 1 - 等比缩放 # 1 load 2 info 3 resize 4 check import cv2img cv2.imread(image0.jpg, 1) im…

软件工程详细知识点复习(上)

文章目录一、软件工程概述1、软件与软件危机2、软件工程二、可行性研究三、需求分析四、概要设计五、详细设计一、软件工程概述 1、软件与软件危机 软件程序数据文档 1、软件危机的主要表现 软件不能满足用户需求软件开发成本严重超标&#xff0c;开发周期大大超过规定日期…

网络设备安装上线,你要知道的10个步骤

大家好&#xff0c;我是技福的小咖老师。在网络工程中设备的安装工作必不可少&#xff0c;你平时都是按哪些步骤完成的&#xff1f;今天给大家总结一下最常见的10个步骤。 安装流程 网络设备安装流程图 安装环境要求 1► 安装场景 为确保设备的正常运行&#xff0c;延长设备…

C. Infected Tree(思维+DFS)

Problem - 1689C - Codeforces Byteland是一片美丽的土地&#xff0c;因其美丽的树木而闻名。 米沙发现了一棵有n个顶点的二叉树&#xff0c;编号从1到n。二叉树是一个无环连接的双向图&#xff0c;包含n个顶点和n-1条边。每个顶点的度数最多为3&#xff0c;而根是数字为1的顶…

基于STM32G431嵌入式学习笔记——五、NVIC中断(以串口UART中断为例)

一、基础知识 1.专业术语 2.NVIC简介 ①在这里要注意&#xff0c;中断控制是分级处理的 ②是否请求中断是中断源控制的。 ③是否响应中断是响应方控制的。 ④以外部中断为例&#xff0c;外部中断请求顺序就是首先从请求的外部设备中选出优先级最高的一个设备待中断&#xff0c…

唐山盐碱滩成渤海明珠 国稻种芯·中国水稻节:河北曹妃甸大米

唐山盐碱滩成渤海明珠 国稻种芯中国水稻节&#xff1a;河北曹妃甸大米 新华社音视频部制作 记者 杨世尧 河北新闻网讯 王士波 赵诤国 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康…

电脑怎么迁移游戏资源,数据迁移能把游戏数据迁移吗

概述&#xff1a;玩家们在打游戏的过程中&#xff0c;会产生很多数据&#xff0c;尤其是那些大型游戏的玩家&#xff0c;都会珍惜游戏数据。电脑怎么迁移游戏资源&#xff1f;如果您刚刚购买了一台新电脑&#xff0c;并且正在寻找将游戏迁移到新电脑的方法&#xff0c;相信本文…

8 张图 | 剖析 Eureka 的首次同步注册表

注册表对于注册中心尤为重要&#xff0c;所有的功能都是围绕这个注册表展开。比如服务 A 要想访问服务 B&#xff0c;就得知道服务 B 的 IP 地址和端口号吧。如下图所示&#xff0c;传统的方式就是服务 A 知道了服务 B 的地址后&#xff0c;发送 HTTP 请求到对应的 API 地址上。…

MySQL事务管理 MVCC,隔离性详解

目录事务管理事务背景什么是事务&#xff1f;事务的四个属性为什么会出现事务?MySQL支持事务的版本事务提交方式事务常见操作方式演示(体现原子性和持久性)操作注意事项结论事务隔离性查看与设置隔离性各种隔离性演示读未提交【Read Uncommitted】脏读读提交【Read Committed】…