谈谈MVCC机制

news2024/12/23 15:02:45

在MySQL中,MVCC(多版本并发控制)是InnoDB存储引擎使用的并发控制机制。它提供对数据的并发访问,并确保多用户环境中数据的一致性和隔离性。

InnoDB通过“Undo log”存储每条记录的多个版本,提供历史记录供读取,并允许不同的事务访问不同的数据版本。在事务期间,客户端只能看到当前事务开始之前提交的记录以及当前事务内所做的修改。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。

隔离级别

MySQL中有4种隔离级别:

READ UNCOMMITED

当前事务可以读取未提交的数据。这些数据可能会回滚,所以我们将未提交的数据称为脏数据,这种问题称为脏读。

READ COMMITED

当前事务确实可以读取已提交的数据,因此不存在脏读问题。但是,如果当前事务多次读取同一条记录,则可能检索到不同的数据。这是因为,在当前事务期间,可能有其他事务修改并提交了该记录。此问题称为不可重复读。

REPETABLE READ

事务多次读取特定的记录集,即使其他事务在事务过程中修改或提交对这些记录的更改,它也始终会获得这些记录的相同值。但是,如果我们在当前事务中多次执行“SELECT COUNT(*) FROM {table_name}”,我们可能会看到不同的结果,这个问题称为幻读。

REPEATABLE READ 是 MySQL InnoDB 中的默认隔离级别。

SERIALIZABLE

所有事务都强制排序,解决了脏读、不可重复读、幻读等问题。但Serialized隔离级别性能较差,因此在实际中很少使用。

MVCC 仅适用于 READ COMMITTED 和 REPEATABLE READ 隔离级别,因为 READ UNCOMMITTED 始终读取最新记录,而 SERIALIZABLE 会为其读取的所有记录添加锁。

概念

TRANSACTION ID

当一个新的事务开始时,它会得到一个自增的事务ID,通过它InnoDB可以知道每个事务的执行顺序。

隐藏列

InnoDB中的每条记录都有两个隐藏列“db_trx_id”和“db_roll_pointer”,如果表中没有主键或非空唯一键,InnoDB将生成一个隐藏的自增列“db_row_id”。

字段名称描述
db_trx_id记录操作该行的事务的事务id
db_roll_pointerundo指针,指向该行的undo日志

InnoDB 在撤消日志中记录“插入”、“更新”和“删除”操作。然而,对于“删除”操作,InnoDB实际上将其记录为“更新”操作,即通常所说的“软删除”。InnoDB 不是物理删除该行,而是更新“已删除标志”来指示该行已被逻辑删除。此方法允许检索该行的先前版本,如果该行被永久删除,则无法检索先前版本。

当前读

一些 SQL 语句,例如“SELECT * ... LOCK IN SHARE MODE(共享锁)”、“SELECT * ... FOR UPDATE(独占锁)”、“UPDATE”、“DELETE”和“INSERT”, 考虑当前的读取操作。这些操作读取该行的最新版本。在读取过程中,InnoDB通过对当前记录加锁来确保没有其他事务可以修改当前记录。

快照读

没有加锁的 SELECT 语句被视为快照读取操作,通过 MVCC 读取所需的版本。快照读取无锁,有效提升事务性能。

本质上,快照是一种以空间换取时间的方式。

Undo log

Undo log存储修改行的先前版本。在行被修改之前,InnoDB会将当前版本复制到Undo log中,Undo log具有以下功能:

  • 如果事务回滚,InnoDB可以找到以前的版本来恢复。

  • 如果当前版本对于当前事务不可见,则会通过undo log查找可见版本。

前面提到,InnoDB将删除操作记录为更新操作,因此Undo Log中只有两种操作:

  • Insert undo log:由insert操作产生,仅用于事务回滚,事务提交后可立即丢弃。

  • 更新undo log:由更新操作生成,不仅用于事务回滚,还用于快照读取。

版本链

当多个事务同时操作同一条记录时,每个事务都会生成一个新的版本,这些版本通过 db_roll_pointer 形成一个链表,称为版本链。

 

Read View

ReadView是事务执行快照读取时生成的记录快照。

读取视图存储当前事务开始之前的所有活动事务。有 4 个重要属性:

  • trx_ids:活动事务ID(不包括当前事务和已提交事务)。

  • low_limit_id:分配的下一个交易ID。

  • up_limit_id:trx_ids中的最小交易id,如果trx_ids为空,则up_limit_id等于low_limit_id。

  • Creator_trx_id:生成读取视图的事务ID。

以下规则用于检查记录是否对当前事务可见:

  • 如果访问版本的事务ID=creator_trx_id,则表示当前事务访问了自己修改过的记录,则该版本对当前事务可见。

  • 如果访问版本的事务ID < up_limit_id,则说明生成该版本的事务在当前事务生成ReadView之前已经提交,因此该版本可以被当前事务访问。

  • 如果访问版本的事务ID > low_limit_id 值,则说明生成该版本的事务是在当前事务生成ReadView之后打开的,因此当前事务无法访问该版本。

  • 如果访问版本的事务ID在up_limit_id和m_low_limit_id之间,则需要判断该版本的事务ID是否在trx_ids列表中。如果是,说明该版本生成的事务在ReadView创建时仍然处于活动状态,该版本无法访问。

  • 如果没有,说明创建ReadView时生成该版本的事务已经提交,可以访问该版本。

MVCC实现原理

了解了上面的概念后,MVCC的实现就很好理解了。

查询流程

  1. 获取交易自己的交易ID,称为trx_id。(这不是在 SELECT 语句期间获得的,而是在事务开始时获得的,即执行 BEGIN 时获得的。)

  2. 检索 ReadView(仅在 SELECT 语句期间生成)。

  3. 在数据库表中,如果找到数据,则将其与ReadView中的事务版本号进行比较。4、如果不符合ReadView的可见性规则,则需要Undo Log中的历史快照,直到返回符合规则的数据。

InnoDB通过ReadView和Undo Log的结合来实现MVCC。Undo Log 存储历史快照,而 ReadView 的可见性规则有助于确定当前版本数据的可见性。

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

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

相关文章

Python数据结构与算法——数据结构(链表、哈希表、树)

目录 链表 链表介绍 创建和遍历链表 链表节点插入和删除 双链表 链表总结——复杂度分析 哈希表(散列表) 哈希表介绍 哈希冲突 哈希表实现 哈希表应用 树 树 树的示例——模拟文件系统 二叉树 二叉树的链式存储 二叉树的遍历 二叉搜索树 插入 查询 删除 AVL树 …

后端SpringBoot+Mybatis 查询订单数据库奇怪报错加一

排错过程&#xff1a; 看报错意思是SQL语句存在错误&#xff0c;然后使用图形化工具运行这个SQL语句 其实这里稍微细心想一下就能发现问题&#xff0c;但是当时没深入想&#xff0c;就觉得order表前加了数据库名字影响不大&#xff0c;所以感觉SQL语句是没问题的&#xff0c;然…

Java6升级至Java8常用新特性

目录 Java 8 常用新特性1、Lambda 表达式2、方法引用2.1 静态方法引用2.2 特定对象的实例方法引用2.3 特定类型的任意对象的实例方法引用2.4 构造器引用 3、接口中的默认方法4、函数式接口4.1 自定义函数式接口4.2 内置函数式接口 5、Date/Time API6、Optional 容器类型7、Stre…

【Qt】窗口

目录 一、概述二、菜单栏&#xff08;QMenuBar&#xff09;三、工具栏&#xff08;QToolBar&#xff09;四、状态栏&#xff08;QStatusBar&#xff09;五、浮动窗口六、对话框 一、概述 Qt窗口是通过QMainWindow类来实现的。 QMainWindow是一个为用户提供主窗口程序的类&…

程序数据模型由OS还是硬件架构决定?

文章目录 前言硬件架构的作用OS的作用编译器的角色OS的数据模型参考 前言 在文章 1>>32的结果是1还是0 中提到了数据模型 L P 64 LP64 LP64 &#xff0c;并提出这个数据模型主要是由 U n i x Unix Unix 以及类 U n i x Unix Unix 的操作系统使用居多&#xff0c;例如…

SpringBoot 缓存预热

简介&#xff1a; SpringBoot集合RedisUtil和 CommadnLinRunner实现缓存预热 一、新建一个缓存抽象类 在redis模块里面 新建 /*** 缓存抽象类*/ Component public abstract class AbstractCache {// 初始化缓存public void initCache() {}public <T> T getCache(Strin…

虚拟现实(VR)项目的开发工具

虚拟现实&#xff08;VR&#xff09;项目的开发涉及到多种工具&#xff0c;这些工具可以帮助开发者从建模、编程到最终内容的发布。以下是一些被广泛认可的VR开发工具&#xff0c;它们覆盖了从3D建模到交互设计等多个方面。北京木奇移动技术有限公司&#xff0c;专业的软件外包…

PySpark的学习

一. 什么是PySpark 使用过的bin/pyspark 程序 , 要注意 , 这个只是一个 应用程序 , 提供一个 Python 解释器执行环境来运行 Spark 任务 现在说的 PySpark, 指的是 Python 的运行类库 , 是可以在 Python 代码中 :import pyspark PySpark 是 Spark 官方提供的一个 Python …

MP设置动态表名

Mybatis设置动态表名 Mybatis设置动态表名1.动态表名插件2.传递表名3.注意事项 Mybatis设置动态表名 1.动态表名插件 MybatisPlus中提供了一个动态表名的插件&#xff1a;https://baomidou.com/pages/2a45ff/#dynamictablenameinnerinterceptor 插件的部分源码如下&#xff…

【SpringCloud】Eureka注册中心

目 录 一.Eureka的结构和作用二.搭建 eureka-server1. 创建 eureka-server 服务2. 引入 eureka 依赖3. 编写启动类4. 编写配置文件5. 启动服务 三.服务注册1. 引入依赖2. 配置文件3. 启动多个user-service实例 四.服务发现1. 引入依赖2. 配置文件3. 服务拉取和负载均衡 总结 假…

【MATLAB源码-第24期】基于matlab的水声通信中海洋噪声的建模仿真,对比不同风速的影响。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 水声通信&#xff1a; 水声通信是一种利用水中传播声波的方式进行信息传递的技术。它在水下环境中被广泛应用&#xff0c;特别是在海洋科学研究、海洋资源勘探、水下军事通信等领域。 1. **传输媒介**&#xff1a;水声通信利…

【IC前端虚拟项目】mvu顶层集成的原则与技巧

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 截止目前,所有的子模块编码均宣告完成,接下来就是封装顶层的时刻了。我自己规划和集成顶层一般有一个习惯,就是在top层下面封装core层和其他模块,比如mvu的top层下例化了mvu_reg和mvu_core两个模块,…

鸿蒙OS开发实战:【网络管理HTTP数据请求】

一、场景介绍 应用通过HTTP发起一个数据请求&#xff0c;支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。 二、 接口说明 HTTP数据请求功能主要由http模块提供。 使用该功能需要申请ohos.permission.INTERNET权限。 涉及的接口如下表&#xff0c;…

最优算法100例之18-列升序行升序的数组中查找元素

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样一…

WebScraper网页数据爬取可视化工具使用(无需编码)

前言 Web Scraper 是一个浏览器扩展&#xff0c;可以实现无需编码即可爬取网页上的数据。只需按照规则进行配置&#xff0c;即可实现一键爬取导出数据。 安装 进入Google应用商店安装此插件&#xff0c;安装步骤如下&#xff1a; 进入Google应用商店需要外网VPN才能访问&…

贪吃蛇:从零开始搭建一个完整的小游戏

目录 导语&#xff1a; 一、游戏框架 二、蛇的实现 三、绘制游戏界面 四、食物 五、移动蛇 六.得分系统&#xff0c;是否吃到食物 七、检查碰撞 八、处理按键事件 九、得分系统 十、游戏状态管理 导语&#xff1a; 贪吃蛇这个经典的小游戏&#xff0c;我上学的时候就…

用一个程序解决SQLite常见的各项操作(实用篇)

文章说明&#xff1a; 本篇文章是在之前的一篇文章SQLite3进行数据库各项常用操作基础上写的&#xff0c;将SQLite涉及到的常用的几种操作&#xff0c;以函数的形式处理成相互调用的形式。 因为之前的文章对基础操作已经解释过了&#xff0c;所以这里直接放置可执行代码和结果…

常见6种开源协议比较

前言 常见的开源许可协议有6种是比较常见和广泛使用的&#xff0c;每种协议都有其特定的使用场景和约束条件。这6种分别是GPL, LGPL&#xff0c;MIT许可证&#xff0c; Apache许可证&#xff0c;BSD许可证和Mozilla Public License&#xff08;MPL&#xff09;. 6种开源许可协议…

深度学习评价指标(1):目标检测的评价指标

1. 简述 在计算机视觉/深度学习领域&#xff0c;每一个方向都有属于自己的评价指标。通常在评估一个模型时&#xff0c;只需要计算出相应的评价指标&#xff0c;便可以评估算法的性能。同时&#xff0c;所谓SOTA&#xff0c;皆是基于某一评价指标进行的评估。 接下来&#xff0…

GitHub - 使用SSH进行连接

文章目录 前言开发环境单个SSH密钥1.1. 生成SSH密钥1.2. 添加SSH密钥1.3. 测试SSH连接2.1. 简化密钥密码输入 多个SSH密钥1.1. 生成/添加/测试SSH密钥2.1. 简化密钥密码输入 无密码密钥补充内容最后 前言 有一个SSH密钥跟了我很多年&#xff0c;更换电脑也不曾更换它。它不需要…