SQL进阶理论篇(十二):InnoDB中的MVCC是如何实现的?
文章目录
- 简介
- 事务版本号
- 行记录的隐藏列
- Undo Log
- Read View的工作流程
- 总结
- 参考文献
简介
在不同的DBMS里,MVCC的实现机制是不同的。本节我们会以InnoDB举例,讲解InnoDB里MVCC的实现机制。
我们需要掌握这么几个概念:
- 事务版本号
- 行记录的隐藏列
- Undo Log
- Read View
事务版本号
什么是事务版本号?
每开启一个事务,我们就会从数据库中获得一个事务ID,这个ID就是事务的版本号。它是自增长的,通过这个ID,我们就可以判断不同事务的时间顺序。
行记录的隐藏列
什么是行记录的隐藏列?
InnoDB的叶子段里存储了数据页,数据页中保存了行记录,而在行记录里有一些比较重要的隐藏字段。
如图:

db_row_id:隐藏的行ID,用来生成默认的聚集索引。如果我们在创建数据表的时候没有指定聚集索引,那么InnoDB就会使用这个隐藏的行ID来创建聚集索引。借以提升查找效率。
db_trx_id:操作这个数据的事务ID,其实就是最后一个对该数据进行插入或者更新的事务ID。
db_roll_ptr:回滚指针,指向这个记录的Undo Log信息。
Undo Log
什么是Undo Log
InnoDB把行记录快照保存在了Undo Log里。
如图所示:

由上图可见,回滚指针其实是将这个数据行的所有快照记录,通过链表结构串联了起来。每个快照记录都保有了操作的事务ID。
当想要找历史快照的时候,就遍历回滚指针查找即可。
Read View的工作流程
read view是如何工作的?
这个比较复杂。
首先它有什么作用,我们前面讲过,Undo Log里保存了很多历史快照,那么对一个事务来讲,它应该查询哪个历史快照呢?
这时候就需要用到Read View了,其解决了行的可见性问题。
一个事务在开启时,会创建属于自己的Read View,这里面保存了事务开启时所有活跃(还没有提交)的事务列表。换个角度理解,这里面保存的其实是不应该让当前事务看到的其他所有事务。(还没提交的事务的内容,原则上是不应该被别人看到的)
Read View里有几个重要的属性:
- trx_ids:其他活跃事务的ID集合;
- low_limit_id:trx_ids中最大的事务ID;
- up_limit_id:trx_ids中最小的事务ID;
- creator_trx_id:创建这个Read View的事务ID。
如图所示,下面是一个trx_ids集合,其中最大事务为trx8,最小事务是trx2,当前事务是creator_trx_id。

如果当前事务想要读取某一行记录,而这一行记录保存的最后修改事务ID是trx_id_line,那么有这么几种情况:
如果trx_id_line < up_limit_id,即当前最小活跃事务,就说明在这些活跃事务创建之前,这个行记录就已经被提交了,那么这个行记录对该事务,应该是可见的。
如果trx_id_line > low_limit_id,说明该行记录在这些活跃的事务创建之后才创建,这个行记录对当前事务应该不可见。
如果 up_limit_id < trx_id_line < low_limit_id,说明trx_id_line 这个事务,可能在当前事务创建的时候,还处于活跃状态,所以我们可以去trx_ids里去遍历。如果找到的话,说明这个事务还没提交,那么这条记录应该不可见,没找到的话,说明事务已经提交了,该行记录可见。
原理简单的说,就是在creator_trx_id这个事务创建的时候,如果trx_id_line这个事务是活跃的,那么它对应的行记录是不可见的;如果不是活跃的,那么对应的行记录就是可见的。这个其实就是避免脏读的概念。只不过是通过事务ID大小比较的方式来实现的。
最后,我们串一串完整的流程,当查询一条记录的时候,系统到底是如何通过多版本并发控制技术来找到它的:
- 获取当前事务自己的版本号,即事务ID;
- 获取自己的Read View;
- 查询得到的行记录数据,与Read View中的活跃事务版本号进行比较;
- 如果行记录符合Read View的规则,即行记录对当前事务可见,那就直接读这条行记录;如果行记录不符合Read View的规则,即行记录对当前事务不可见(原因见上),那就去Undo Log里获取该行记录符合情况的历史快照;
- 最后返回符合规则的数据。
因此,在InnoDB中,MVCC是通过Undo Log + Read View来进行数据读取,Undo Log保存了数据的历史快照,而Read View帮助我们判断当前最新版本的数据是否可见,不可见,那就去Undo Log里取历史。
总结
MVCC是通过乐观锁思想,来保证事务的隔离。
MVCC 的核心就是 Undo Log+ Read View,“MV”就是通过 Undo Log 来保存数据的历史版本,实现多版本的管理,“CC”是通过 Read View 来实现管理,通过 Read View 原则来决定数据是否显示。
需要注意,针对不同的隔离级别,Read View 的生成策略不同。或者说,根据Read View的生成策略不同,MVCC得以实现不同的隔离级别。
当隔离级别是读已提交时,一个事务中,每次select查询都会获取一次Read View,如果每次获取到的Read View不同,就会产生不可重复读或者幻读的情况。
当隔离级别是可重复读的时候,一个事务只在第一次select 的时候获取一次Read View,之后的select都是对这个Read View的复用(解决了不可重复读的问题)。同时,在可重复读的隔离级别下,InnoDB会采用MVCC + Next-Key锁的机制来避免幻读问题。
那当隔离级别是读未提交时,就不合适用MVCC来控制了。因为根本就不需要用版本控制了,大家都直接读最新的行记录就可以了。
InnoDB中有三种行级锁:
- 记录锁:对单个行记录添加锁;
- 间隙锁(Gap Locking):锁住一个范围,但不包括记录本身。采用间隙锁可以防止幻读的产生(应该是锁住范围,不让范围增加或者减少,但是对记录的update应该还是可以的,估计防止不了不可重复读)。
- Next-Key锁:锁住一个范围,同时锁定范围本身,相当于是间隙锁+记录锁。
在读已提交的情况下,InnoDB采用的是记录锁;在可重复读的隔离级别下,InnoDB会采用Next-Key锁的机制。
参考文献
- 31丨为什么大部分RDBMS都会支持MVCC?
相关文章:
SQL进阶理论篇(十二):InnoDB中的MVCC是如何实现的?
文章目录 简介事务版本号行记录的隐藏列Undo LogRead View的工作流程总结参考文献 简介 在不同的DBMS里,MVCC的实现机制是不同的。本节我们会以InnoDB举例,讲解InnoDB里MVCC的实现机制。 我们需要掌握这么几个概念: 事务版本号行记录的隐藏…...
SpringCloudAliBaba篇之Seata:分布式事务组件理论与实践
1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中,一个事务由一组SQL语句组成,事务具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID原则。 原子性(atomici…...
在centos7.9上安装Jenkins的安装过程
1.jenkins的安装和配置: 安装JDK: yum install -y fontconfig java-11-openjdk # 安装目录:/usr/lib/jvm # fontconfig 是 Linux 系统中用于配置和管理字体的一种工具 下载jenkins安装包: sudo wget -O /etc/yum.repos.d/jenkins…...
uni-app基本标签
导航栏设置 - navigationBarBackgroundColor: 设置导航栏的背景颜色(全局页面) - navigationBarTextStyle: 导航栏标题颜色(仅支持 black 和 white) - navigationBarTitleText: 设置导航栏标题内容 - enablePullDownRefresh: 是否…...
《PySpark大数据分析实战》-14.云服务模式Databricks介绍基本概念
📋 博主简介 💖 作者简介:大家好,我是wux_labs。😜 热衷于各种主流技术,热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员(PCTA)、TiDB数据库专家(PCTP…...
微信小程序校园跑腿系统怎么做,如何做,要做多久
在这个互联网快速发展、信息爆炸的时代,人人都离不开手机,每个人都忙于各种各样的事情,大学生也一样,有忙于学习,忙于考研,忙着赚学分,忙于参加社团,当然也有忙于打游戏的&#x…...
当我分别问8款GPT一个问题。。。
前两天下班在地铁上无聊寻思问一下不同的GPT一个相同的问题,哪个会给出我比较满意的答案,然后我就提问:我老妹有点憨怎么办?(ps:开玩笑的,嘻嘻。。。) 很明显其他GPT都给出了大差不差…...
Elasticsearch 8.9 search命令执行查询源码
一、相关的API的handler1、接收HTTP请求的handler2、往数据节点发送查询请求的action(TransportSearchAction)3、通过transportService把查询请求发送到指定的数据节点 二、数据节点收到请求的处理逻辑1、尝试从缓存中加载查询结果2、不通过缓存查询,直接执行查询(1…...
【PHP】身份证正则验证、校验位验证
目录 1.正则 简单正则 详细正则 2.校验位验证 1.正则 简单正则 function isValidIdCardNumber($idCardNumber) {// 身份证号长度为 15 位或 18 位$pattern /^(?:\d{15}|\d{17}[\dxX])$/;return preg_match($pattern, $idCardNumber); }$idCardNumber 12345678901234567…...
Matlab示例-Examine 16-QAM Using MATLAB学习笔记
工作之余学习16-QAM 写在前面 网上看到许多示例,但一般都比较难以跑通。所以,还是老方法,先将matlab自带的例子研究下。 Examine 16-QAM Using MATLAB Examine 16-QAM Using MATLAB 或者,在matlab中,键入&#x…...
ArcGIS Pro SDK运行消息只提示一次
工具大部分都是异步执行,所以提示信息需要异步执行完再进行,所以注意async和await的使用。 相关async和await的文章请查看C# 彻底搞懂async/await_c# async await-CSDN博客 public async Task InformationPrompt() {string message String.Empty;await ArcGIS.De…...
通话状态监听-Android13
通话状态监听-Android13 1、Android Telephony 模块结构2、监听和广播获取通话状态2.1 注册2.2 通话状态通知2.3 通话状态 3、通知状态流程* 关键日志 frameworks/base/core/java/android/telephony/PhoneStateListener.java 1、Android Telephony 模块结构 Android Telephony…...
无懈可击的防泄密之旅:迅软DSE在民营银行的成功实践
客户简要介绍 某股份有限公司主体是中部地区的民营银行,由其母公司联合9家知名民营企业共同发起设立。正式开业于2016年,紧紧围绕目标产业生态圈和消费金融,着力打造产业银行、便捷银行、数字银行、财富管理银行为一体的BEST银行,…...
【送书活动】智能汽车、自动驾驶、车联网的发展趋势和关键技术
文章目录 前言01 《智能汽车》推荐语 02 《SoC底层软件低功耗系统设计与实现》推荐语 03 《SoC设计指南》推荐语 05 《智能汽车网络安全权威指南(上册)》推荐语 06 《智能汽车网络安全权威指南(下册)》推荐语 后记赠书活动 前言 …...
不同版本QT使用qmake时创建QML项目的区别
不同版本QT使用qmake时创建QML项目的区别 文章目录 不同版本QT使用qmake时创建QML项目的区别一、QT5新建QML项目1.1 目录结构1.2 .pro 文件内容1.3 main.cpp1.4 main.qml 二、QT6新建QML项目2.1 目录结构2.2 .pro文件内容2.3 main.cpp2.4 main.qml 三、两个版本使用资源文件的区…...
【PHP入门】1.1-PHP初步语法
-PHP语法初步- PHP是一种运行在服务器端的脚本语言,可以嵌入到HTML中。 1.1.1PHP代码标记 在PHP历史发展中,可以使用多种标记来区分PHP脚本 ASP标记: <% php代码 %>短标记: <? Php代码 ?>,以上两种…...
如何在jenkins容器中安装python+httprunner+pytest+git+allure(一)
背景: API接口自动化使用python语言实现,利用httprunner框架编写自动化用例场景(执行的时候还是依赖pytest),使用jenkins自动构建git上的源代码,并产生allure报告可视化展示API执行结果。 步骤 1.进入jenkins容器 注意使用roo…...
Android终端模拟器Termux上使用Ubuntu
Termux 上安装各种 Linux 系统是通过 proot-distro 工具来实现的,所以先安装一下 proot-distro 工具。 ~ $ pkg install proot-distro 查看Termux支持安装那些Linux ~ $ proot-distro listSupported distributions:* Alpine LinuxAlias: alpineInstalled: noComme…...
【神器】wakatime代码时间追踪工具
文章目录 wakatime简介支持的IDE安装步骤API文档插件费用写在最后 wakatime简介 wakatime就是一个IDE插件,一个代码时间追踪工具。可自动获取码编码时长和度量指标,以产生很多的coding图形报表。这些指标图形可以为开发者统计coding信息,比如…...
UML统一建模语言
一、建模语言的背景: 通俗地阐述就是:客户一开始不知道要什么,开发通过客户的阐述进行理解和分析,这个过程中间可能会产生一些误解。为了避免此类事件,所以需要建模。类似于要建造一栋楼,建筑设计师根据住…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
