MySQL之MVCC如何实现可重复读和提交读

(/≧▽≦)/~┴┴ 嗨~我叫小奥 ✨✨✨
👀👀👀 个人博客:小奥的博客
👍👍👍:个人CSDN
⭐️⭐️⭐️:Github传送门
🍹 本人24应届生一枚,技术和水平有限,如果文章中有不正确的内容,欢迎多多指正!
📜 欢迎点赞收藏关注哟! ❤️

文章目录

    • 如何实现可重复读
    • 如何实现提交读
    • 总结

如何实现可重复读

今天来带大家学习一下,MVCC是如何实现可重复读的。

假设事务A和事务B同时堆主键id = 1的记录进行操作,事务A和B的事务id分别为20和30 。

在这里插入图片描述

那么这两个事务就会创建各自的ReadView:

在这里插入图片描述

此时事务A的creator_trx_id = 20,事务B的creator_trx_id = 30。由于仅有两个活跃的事务,所以事务列表中最小的事务是事务A,所以min_trx_id = 20,下一个也就是最大的事务id的max_trx_id值应该为事务B的下一个id,即max_trx_id = 31

事务A去读取主键id为1的数据,找到记录之后就会查看该记录的trx_id,假设事务A查询到该记录的trx_id为10 。

随后和自己的creator_trx_id进行比较:

在这里插入图片描述

发现主键id = 1的记录 trx_id = 10 < A.creator_trx_id = 20,就判断到该记录的事务id不存在于活跃的事务列表中小于自己的事务id,这代表本次记录的值是在自己查询之前提交的,所以可以读取,并且在读取完之后,将该记录的trx_id修改为自己的事务id。

在这里插入图片描述

然后,把age字段的值从28修改为30 。

在这里插入图片描述

另外,被修改的字段还有Undo Log中的另一个隐藏字段:roll_pointer指针。它会去指向被事务A修改的之前的数据版本,也就是fancy的年龄为28的数据的地址,就是为了用来记录,方便下次被查询。

在这里插入图片描述

随后,事务B也对该条数据进行操作,事务B的要求是将fancy的年龄从30直接修改为50 。

此时会再次进行一次trx_id的比较过程,去判断自己的creator_trx_id是否大于这条记录对应的trx_id,如果大于,就去修改这条记录的值,将年龄从30修改为50:

在这里插入图片描述

并且Undo Log版本链也会更新对应的数据。

在这里插入图片描述

重点来了

如果此时事务A再去读取主键id = 1这条记录,发现这条记录的trx_id已经被修改为了30,再次进行事务id之间的区间比较:发现 A.trx_id = 20 < 主键 id = 1 记录.trx _id = 30 < max_trx_id = 31,并且trx_id = 30 存在于活跃事务集合m_ids中,就代表自己读取到的是和自己同一时间范围内一块启动的另一个未提交的活跃事务所修改的值。

在这里插入图片描述

那么此时事务A是不会去读取这条记录对应的数据的,它会通过Undo Log版本链上的roll_pointer指向的地址去查找上一个旧版本的记录,直到找到第一条trx_id小于等于自己的事务id并且不存在于活跃事务id集合m_ids列表中的记录,代表是别的事务已经提交的最后一条记录然后读取它。

在这里插入图片描述

这样的话,每一个事务去读取或者修改同一个记录时,只能操作已经提交的数据,未提交的数据时不能被读取到的,MySQL就这样实现了可重复读。

其实本质上就是通过Read View的字段判断这行记录是否对自己可见,如果不可见的话再去找Undo Log里面的记录,直到找到对自己可见的数据,然后才能进行操作。

如何实现提交读

提交读能够解决脏读,脏读问题其实本质上就是一个事务读取到了另一个事务没有提交的内容。

下面我们来学习一下MVCC是如何实现提交读的。

假设事务A和事务B同一时刻启动,事务B将同一行的记录,也就是fancy的年龄改成了25,但是事务B并没有提交,此时事务A就会去读取这条记录的trx_id

在这里插入图片描述

在这里插入图片描述

事务A查看到该记录的trx_id居然比事务A的Read View列表中的creator_trx_id值大,并且修改这条记录的事务trx_id存在于自己的m_ids列表里面,那么事务A就可以判断到该记录是被另一条没有提交的事务修改的,所以它不会去读取这条数据的内容,事务A会通过Undo Log版本链继续找第一条trx_id 小于等于自己的事务id并且不在m_ids列表里面的数据。

所以,事务A不会看到事务B正在修改的数据,脏数据也不会产生。

总结

InnoDB 中,MVCC 就是通过 Undo Log + Read View 进行数据读取,Undo Log 保存了历史快照,而 Read View 规则帮我们判断当前版本的数据是否可见。从而不需要通过加锁的方式,就可以实现提交读和可重复读这两种隔离级别。

总的来说,MVCC本质上就是一种数据结构。已提交读和可重复读都是使用了Read View这种策略通过区间判断获取自己能够读取的内容,然后展示。InnoDB通过MVCC,解决了脏读、不可重复读。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql安装及操作

一、Mysql 1.1 MySQL数据库介绍 1.1.1 什么是数据库DB&#xff1f; DB的全称是database&#xff0c;即数据库的意思。数据库实际上就是一个文件集合&#xff0c;是一个存储数据的仓库&#xff0c;数据库是按照特定的格式把数据存储起来&#xff0c;用户可以对存储的数据进行…

查看 Debian 系统版本的 6 种方式

本篇文章将为大家介绍 6 种查看 Dibian 系统发行版本号的方式。 1. 使用 lsb_release 命令 lsb_release 命令可用于查看 Linux 发行版操作系统的具体版本。它可能尚未安装在你的操作系统中&#xff0c;因此你需要先安装它。运行以下命令来安装 lsb_release&#xff1a; apt-…

Qt/QML编程之路:画线及倒车影响(48)

前言: 倒车影像中有一个属性比较实用,那就是倒车线,这条线很明显会在视频图像上叠加显示,或者说在视频上面一个图层画的线。这里有一个画线的Qt示例,用于在一个scene上画一个对角线: #include "mainwindow.h" #include <QApplication> #include <QtW…

Antd Pagination 解决点击重置按钮后分页器不刷新问题

问题描述&#xff1a; 原本&#xff1a; 问题&#xff1a; 解决方法&#xff1a; const [resetPageSize, setResetPageSize] useState(10); setResetPageSize(10) pageSize{resetPageSize} pageSizeChange //初始化const [resetPageSize, setResetPageSize] useState(10);//…

排序(冒泡/快速/归并)

冒泡排序 时间复杂度为 O(n^2) 原理 比较相邻的元素. 如果第一个比第二个大,就交换他们两个.依次比较每一对相邻的元素—>结果 : 最后的元素是这组数中最大的重复上述步骤 , 除了最后一个[]因为最后一个已经是排好序的了(这组数中最大的那个)]持续对越来越少的元素进行如上…

【真题解析】题目 3151: 蓝桥杯2023年第十四届省赛真题-飞机降落【C++ DFS 超详解注释版本】

爆搜冥想 暴力枚举每一辆飞机对于每一个飞机都只存在两种情况&#xff0c;可以降落和不可以降落如果可以降落&#xff0c;计算降落后最早可以降落的时间pre&#xff0c;作为下一次递归的传参如果不可以降落&#xff0c;枚举下一辆飞机 注意这辆的降落有盘旋这种量子叠加态&…

GIS与Python机器学习:开创地质灾害风险评价新纪元

地质灾害是指全球地壳自然地质演化过程中&#xff0c;由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。由于降水、地震等自然作用下&#xff0c;地质灾害在世界范围内频繁发生。我国除滑坡灾害外&#xff0c;还包括崩塌、泥石流、地面沉…

Jira 软件缺陷管理 (软件测试)

内容来源&#xff1a;总结黑马课程 1.软件缺陷信息 2.创建缺陷问题 2.1 缺陷模板 2.2 创建缺陷问题模板

SAR成像及其干扰样式

SAR成像及其干扰样式 RD算法CS算法wk算法SAR干扰技术射频噪声干扰调幅噪声干扰调频噪声干扰调相噪声干扰噪声卷积干扰乘积干扰移频干扰需要的联系qq&#xff1a;2329738917 RD算法 CS算法 wk算法 SAR干扰技术 射频噪声干扰 调幅噪声干扰 调频噪声干扰 调相噪声干扰 噪声卷积干…

1.5T数据惨遭Lockbit3.0窃取,亚信安全发布《勒索家族和勒索事件监控报告》

本周态势快速感知 本周全球共监测到勒索事件93起&#xff0c;近三周攻击数量呈现持平状态。 本周Lockbit3.0是影响最严重的勒索家族&#xff0c;Blacksuit和Ransomhub恶意家族紧随其后&#xff0c;从整体上看Lockbit3.0依旧是影响最严重的勒索家族&#xff0c;需要注意防范。 …

【C语言】Infiniband驱动__mlx4_init_one函数

一、注释 Linux内核驱动程序中的部分&#xff0c;属于Mellanox网卡驱动mlx4的初始化过程。 // Mellanox 以太网驱动主程序代码 static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,struct mlx4_priv *priv) {int err; // 错误码变量int nvfs[MLX4_MAX_PORTS…

国内IP切换软件:解锁网络世界的新钥匙

在数字化快速发展的今天&#xff0c;互联网已成为我们生活中不可或缺的一部分。然而&#xff0c;伴随着网络使用的深入&#xff0c;许多用户逐渐意识到&#xff0c;不同的IP地址可能会带来截然不同的网络体验。为了应对这一问题&#xff0c;国内IP切换软件应运而生&#xff0c;…