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统一建模语言
一、建模语言的背景: 通俗地阐述就是:客户一开始不知道要什么,开发通过客户的阐述进行理解和分析,这个过程中间可能会产生一些误解。为了避免此类事件,所以需要建模。类似于要建造一栋楼,建筑设计师根据住…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...