MVCC(多版本并发控制)原理实现

MVCC(多版本并发控制)原理实现

  • 一、实现组件
  • 二、数据可见性判断
  • 三、可见性描述

多版本并发控制(MVCC,Multi-Version Concurrency Control),是一种并发控制的方法。

MySQL InnoDB巧妙地利用了隐藏列、事务ID、Read View以及Undo Log等技术,实现了多版本并发控制,使得不同事务能够几乎同时访问数据库而不相互阻塞,极大地提升了数据库系统的并发性能和用户体验。

一、实现组件

事务ID和系统版本号(syscanf_version)

每个事务都有一个全局唯一的事务ID(trx_id),这个ID随着事务的开始而递增。

在InnoDB内部,还有一个系统版本号(syscanf_version),也是随着事务的执行不断增长。

隐藏列与行格式

InnoDB表中每一行数据除了用户定义的列外,还有额外的隐藏列:

  • DB_TRX_ID: 记录最后一次修改该行数据的事务ID。

  • DB_ROLL_PTR: 回滚指针,指向Undo Log中的相应条目,用于撤销操作或者构建历史版本。

  • DB_ROW_ID(可选): 对于没有主键的表,InnoDB会自动生成一个隐含的ROW ID作为聚簇索引的一部分。

Undo Log(回滚日志)

当事务对数据进行修改时,InnoDB不仅在当前的数据页上更新数据,还会在Undo Log(两种类型)中记录旧值以及修改前的状态。

INSERT Undo Log: 记录插入操作,主要用于事务回滚时删除新插入的行。

UPDATE/DELETE Undo Log: 记录更新或删除操作,包含被修改前的行数据,用于事务回滚时恢复原状,同时也为其他事务提供历史版本的数据。

Read View(读视图)

在“可重复读”隔离级别下,每个事务启动时会创建并固定一个Read View,之后的所有一致性非锁定读都会基于这个视图来判断数据可见性,Read View包含了以下关键信息。

  • m_ids[]: 数组存储了所有未提交且活跃的事务ID列表。
  • low_limit_id: 所有小于等于这个值的事务ID已经提交完成。
  • up_limit_id: 下一个即将分配给事务的ID,表示尚未分配事务ID的最大值。
  • creator_trx_id: 创建此Read View的事务自身的事务ID。

二、数据可见性判断

当事务执行SELECT查询时,针对每行数据,根据Read View和该行的DB_TRX_ID来判断是否可见:

  1. DB_TRX_ID小于low_limit_id: 说明该行是在当前事务开始之前就已经提交的,因此对该事务是可见的。

  2. DB_TRX_ID大于等于up_limit_id: 说明该行是由在ReadView之后才开启的事务修改或插入的,因此对当前事务不可见。

  3. DB_TRX_ID位于low_limit_id和up_limit_id之间:

    • 若DB_TRX_ID不在ReadView的m_ids列表中,则该事务已提交,数据行对当前事务可见。
    • 若DB_TRX_ID在ReadView的m_ids列表中,则该事务尚未提交,数据行对当前事务不可见。

对于不可见的行,通过DB_ROLL_PTR找到对应的Undo Log,并从中获取在Read View创建时刻该行的最新已提交版本,以便当前事务查看。

在“可重复读”隔离级别下,由于Read View在事务开始时就固定了,所以即使后续有新的事务插入满足查询条件的新行,这些新行也不会影响当前事务的查询结果,从而避免了幻读问题。

三、可见性描述

一个代码片段,用于简单演示Read View与事务ID的对比逻辑。

// 假设Transaction类代表一个MySQL InnoDB中的事务,它有trxId属性表示当前事务ID
class Transaction {long trxId; // 当前事务ID// 创建一个新的读视图ReadView createReadView() {return new ReadView(this.trxId);}
}
// 代表InnoDB中的一行记录,包含DB_TRX_ID等隐藏列
class InnodbRow {long dbTrxId; // 最后修改该行的事务IDObject[] data; // 用户数据RollbackPointer rollbackPtr; // 回滚指针// 判断此行对于给定ReadView是否可见boolean isVisibleTo(ReadView readView) {if (dbTrxId < readView.lowLimitId) {// 已提交事务修改,对当前事务可见return true;} else if (readView.isTrxIdInRange(dbTrxId)) {// 未提交事务或已提交但在此视图创建后,对当前事务不可见return false;} else {// 不可能出现的情况,理论上应该为已提交事务throw new IllegalStateException("Invalid transaction ID state");}}
}
// ReadView类存储了事务在可重复读隔离级别下看到的数据版本范围
class ReadView {long lowLimitId; // 已提交事务的最小ID界限Set<Long> activeTransactionIds; // 当前未提交的事务ID集合long upLimitId; // 下一个待分配的事务ID(即活跃事务的最大值)long creatorTrxId; // 创建此ReadView的事务ID// 检查给定的事务ID是否在当前活跃的未提交事务范围内boolean isTrxIdInRange(long trxId) {return activeTransactionIds.contains(trxId);}
}
// 假设有两个事务tx1和tx2,以及一行数据row
Transaction tx1 = new Transaction(); // 初始化事务tx1并获取其事务ID
Transaction tx2 = new Transaction(); // 初始化事务tx2并获取其事务ID
InnodbRow row = getRowFromDatabase(); // 获取数据库中一行记录// 在tx1中创建读视图并检查row的可见性
ReadView readView1 = tx1.createReadView();
boolean isVisibleToTx1 = row.isVisibleTo(readView1);// 如果isVisibleToTx1为true,则tx1可以查看该行数据;否则,根据MVCC规则,tx1应查找undo log中的历史版本。

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

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

相关文章

暴雨高性能分布式存储为AI提供坚实数据存力

随着两会的圆满落幕&#xff0c;新质生产力和人工智能的发展成为社会各界热议的焦点。总理在两会后的首次调研中&#xff0c;特别强调了新质生产力和人工智能的重要性&#xff0c;这无疑为人工智能产业的蓬勃发展注入了新的动力。 年初&#xff0c;Sora所引领的人工智能热潮更…

Selenium WebDriver提供By.CSS_SELECTOR定位元素方法

By.CSS_SELECTOR 是 Selenium WebDriver 提供的一种定位元素的方法&#xff0c;它允许使用 CSS 选择器来定位页面上的元素。以下是常见的 CSS 选择器语法&#xff1a; 1. **标签选择器&#xff08;Tag Selector&#xff09;**&#xff1a;通过元素的标签名选择元素。 - 示例…

【入门】保研/考研408机试-基本知识点(输入/出、基本数学、字符串)

目录 一、基础结构方面 1.1调用标准库* 1.2输入输出方面 1.2.1保留几位小数输出* 1.2.2字符/字符串* 1.2.3输入n个数&#xff08;循环用&#xff09; 1.3i和i 二、数学方面 2.1绝对值 2.2幂次方 2.3取整问题 2.4涉及分数计算 三、字符串方面 3.1字符比较 例题&…

Linux中的音频开发

在Linux环境下进行音频开发&#xff0c;你可能会面临多种挑战和任务&#xff0c;从基础的音频播放和录制到复杂的音频处理和流媒体传输。以下是一些音频开发课题和建议&#xff1a; ### 题目1&#xff1a;基础音频播放 **描述**&#xff1a;开发一个简单的命令行应用程序&…

矩阵消元-MIT

文章目录 1. 行变换消元法 1. 行变换消元法 假设我们有一个方程组表示如下&#xff1a; x 2 y z 2 ; 3 x 8 y z 12 ; 4 y z 2 (1) x2yz2;\quad 3x8yz12;\quad4yz2\tag{1} x2yz2;3x8yz12;4yz2(1)矩阵表示如下&#xff1a; [ 1 2 1 3 8 1 0 4 1 ] → [ 1 2 1 0 2 − 2…

【分布式websocket 】前端vuex管理客户端消息crud!使用localStorage来存储【第19期】

前言 聊天系统客户端是要存储消息的&#xff0c;因为所有所有的历史消息都从服务器拉的话一方面服务器压力大&#xff0c;另一方面也耗费用户流量。所以客户端存储消息是势在必行的。如何存储呢上一篇文章也写了&#xff0c;大概就是浏览器的话是localStorage或者IndexedDB。然…

MIT线性代数-方程组的几何解释

文章目录 1. 二维空间1.1 行方向1.2 列方向 2. 三维空间2.1 行方向2.2 列方向 假设有一个方程组 A X B AXB AXB表示如下 2 x − y 0 (1) 2x-y0\tag{1} 2x−y0(1) − x 2 y 3 (2) -x2y3\tag{2} −x2y3(2) 矩阵表示如下&#xff1a; [ 2 − 1 − 1 2 ] [ x y ] [ 0 3 ] (3)…

JavaScript面向对象详解(一)

一. JavaScript的对象 传统的面向对象 面向对象语言的一个标志就是类类是所有对象的统称, 是更高意义上的一种抽象. 对象是类的实例.通过类我们可以创建任意多个具体的对象. 在学习C/OC/Java/Python等编程语言的时候, 都可以按照这种方式去创建类和对象.JavaScript的面向对象…

(四)Android布局类型(线性布局LinearLayout)

线性布局&#xff08;LinearLayout&#xff09;&#xff1a;按照一定的方向排列组件&#xff0c;方向主要分为水平方向和垂直方向。方向的设置通过属性android:orientation设置 android:orientation 其取值有两种 水平方向&#xff1a;android:orientation"horizontal&…

Lua-Lua与C的交互3

Lua与C的交互是指在Lua脚本中调用C语言编写的函数或者在C语言中调用Lua脚本中定义的函数。这种交互可以实现Lua和C语言之间的数据传递和函数调用。 Lua提供了一组API函数&#xff0c;可以在C语言中使用这些函数来与Lua进行交互。通过这些API函数&#xff0c;C语言可以将数据传…

Java中如何解决if-else(策略+枚举)

最近接到了一个新需求&#xff0c;按照不同的编码去执行不同的逻辑&#xff0c;但最后返回的数据类型是一致的&#xff0c;都是相同对象的List集合。 完成这个需求的话可以使用if-else来执行不同的方法&#xff0c;虽然if-else可以实现&#xff0c;但if-else是一种面向过程的实…

MongoDB——linux中yum命令安装及配置

一、创建mongodb-org-3.4.repo文件 vi /etc/yum.repos.d/mongodb-org-3.4.repo 将下面内容添加到创建的文件中 [mongodb-org-3.4] nameMongoDB Repository baseurlhttps://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.4/x86_64/ gpgcheck1 enabled1 gpgkeyhttps://www…

本地用AIGC生成图像与视频

最近AI界最火的话题&#xff0c;当属Sora了。遗憾的是&#xff0c;Sora目前还没开源或提供模型下载&#xff0c;所以没法在本地跑起来。但是&#xff0c;业界有一些开源的图像与视频生成模型。虽然效果上还没那么惊艳&#xff0c;但还是值得我们体验与学习下的。 Stable Diffu…

Ubuntu Linux - Primavera P6 EPPM 安装及分享

引言 根据计划&#xff0c;近日我制作了基于Ubuntu Linux 的P6虚拟机环境&#xff0c;同样里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机&#xff0c;请先与Oracle Primavera销售代表取得联系&#xff0c;以获取所需的应…

无人机助力智慧农田除草新模式,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建无人机航拍场景下的农田杂草检测识别系统

科技发展到今天&#xff0c;无人机喷洒药物已经不是一件新鲜事情了&#xff0c;在很多高危的工作领域中&#xff0c;比如高空电力设备除冰&#xff0c;电力设备部件传送更换等等&#xff0c;无人机都可以扮演非常出色的作用&#xff0c;前面回到老家一段时间&#xff0c;最近正…

吴恩达deeplearning.ai:使用多个决策树随机森林

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 文章目录 为什么要使用树集合使用多个决策树(Tree Ensemble)有放回抽样随机森林XGBoost(eXtream Gradient Boosting)XGBoost的库实现何时使用决策树决策树和树集合神经网络 使用单个决策树的…

数据预处理在数据挖掘中的重要性

数据挖掘作为从大量数据中提取有用信息和知识的过程&#xff0c;其结果的准确性和可靠性直接受到数据质量的影响。因此&#xff0c;数据预处理在数据挖掘中扮演着至关重要的角色。让我们探讨数据质量对数据挖掘结果的影响&#xff0c;并介绍常见的数据预处理方法以及它们如何提…

2024.3.14每日一题

LeetCode 合并数组中的最大元素 题目链接&#xff1a;2789. 合并后数组中的最大元素 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个下标从 0 开始、由正整数组成的数组 nums 。 你可以在数组上执行下述操作 任意 次&#xff1a; 选中一个同时满足 0 < i …

【开源】SpringBoot框架开发房屋出售出租系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 房屋销售模块2.2 房屋出租模块2.3 预定意向模块2.4 交易订单模块 三、系统展示四、核心代码4.1 查询房屋求租单4.2 查询卖家的房屋求购单4.3 出租意向预定4.4 出租单支付4.5 查询买家房屋销售交易单 五、免责说明 一、摘…

短视频矩阵系统/短视频矩阵系统技术saas研发

短视频矩阵系统SaaS研发是一个复杂且需要技术专业知识的工作。以下是一些关键步骤和建议&#xff0c;帮助你开发一个成功的短视频矩阵系统SaaS&#xff1a; 1. 明确需求&#xff1a;首先&#xff0c;你需要明确你的短视频矩阵系统的具体需求&#xff0c;例如用户规模、视频内容…