MySQL InnoDB引擎 MVCC
MVCC(Multi-Version Concurrency Control)即多版本并发控制,是 MySQL 的 InnoDB 存储引擎实现并发控制的一种重要技术。它在很多情况下避免了加锁操作,从而提高了数据库的并发性能。
一、原理
MVCC 的核心思想是通过保存数据在某个时间点的快照来实现并发控制。
在 MVCC 模型下,每个事务在启动时会看到一个数据库的一致性视图,该视图是由事务启动时数据库中所有已提交事务的状态决定的。
事务只能看到在其启动之前,已经提交的事务所做的更改,而看不到在其启动之后其他事务的未提交更改或新插入的数据,这样就避免了脏读、不可重复读等问题。
二、实现方式
InnoDB 存储引擎通过几个关键要素来实现 MVCC,包括隐藏列、回滚段(undo log)、事务 ID 和一致性视图(Read View)。
1. 隐藏列
InnoDB 为表中的每一行记录添加了三个隐藏列:
-
DB_TRX_ID:记录最近一次对该记录进行修改(INSERT、UPDATE)的事务 ID。当一个事务对记录进行插入操作时,会将自己的事务 ID 赋值给该记录的
DB_TRX_ID列。 -
DB_ROLL_PTR:回滚指针,指向该记录的上一个版本所在的回滚段(undo log)。当对记录进行修改时,会将修改前的记录版本信息存储在回滚段中,并通过
DB_ROLL_PTR指针指向该版本。 -
DB_ROW_ID:如果表中没有定义主键且没有唯一的非空索引,InnoDB 会自动为表添加一个隐藏的自增主键
DB_ROW_ID。
2. 回滚段(undo log)
回滚段用于存储记录的旧版本信息。当一个事务对记录进行修改时,会将修改前的记录版本信息存储在回滚段中,并通过 DB_ROLL_PTR 指针将当前记录与旧版本记录连接起来,形成一个版本链。通过版本链,我们可以找到记录在不同时间点的所有版本。
在 MySQL InnoDB 引擎中,回滚段(undo log)的合理配置对于数据库的性能、事务处理以及数据恢复等方面都至关重要。
关键配置参数
1.
innodb_undo_logs
作用:该参数用于设置 InnoDB 存储引擎中回滚段的数量。在 MySQL 5.6 及以后的版本中,默认值通常为 128 个。增加回滚段的数量可以提高并发事务处理能力,因为多个事务可以同时使用不同的回滚段,减少了回滚段的竞争。
配置示例:若要将回滚段数量设置为 256,可以在 MySQL 配置文件(通常是
my.cnf或my.ini)中添加或修改如下配置:[mysqld] innodb_undo_logs = 2562.
innodb_undo_tablespaces
作用:此参数用于指定回滚段所在的表空间数量。从 MySQL 5.6 开始,InnoDB 支持将回滚段存储在独立的表空间中,这样可以更好地管理回滚段的空间。设置多个回滚段表空间可以分散 I/O 负载,提高性能。
配置示例:假设要将回滚段存储在 3 个独立的表空间中,可在配置文件中添加:
[mysqld] innodb_undo_tablespaces = 33.
innodb_max_undo_log_size
作用:该参数限制了单个回滚段文件的最大大小。当回滚段文件达到这个大小后,InnoDB 会尝试回收不再使用的 undo log 空间。如果无法回收足够的空间,可能会导致事务等待或报错。
配置示例:若要将单个回滚段文件的最大大小设置为 2GB,可以在配置文件中添加:
[mysqld] innodb_max_undo_log_size = 2G4.
innodb_undo_log_truncate
作用:这是一个布尔型参数,用于控制是否启用回滚段文件的截断功能。当设置为
ON时,InnoDB 会在合适的时机自动截断回滚段文件,释放不再使用的空间。默认值为OFF。配置示例:若要启用回滚段文件截断功能,可在配置文件中添加:
[mysqld] innodb_undo_log_truncate = ON配置建议
根据并发情况调整回滚段数量:如果数据库中有大量的并发事务,适当增加
innodb_undo_logs的值可以减少回滚段的竞争,提高并发性能。但过多的回滚段也会增加系统管理的开销,需要根据实际情况进行权衡。使用独立的回滚段表空间:将回滚段存储在独立的表空间中(通过设置
innodb_undo_tablespaces)可以提高 I/O 性能,尤其是在高并发场景下。合理设置回滚段文件大小:
innodb_max_undo_log_size的设置需要考虑数据库的事务大小和频率。如果事务较大或频繁,可适当增大该值;反之,则可以减小。启用回滚段文件截断功能:对于长期运行的数据库,启用
innodb_undo_log_truncate可以有效地管理回滚段的空间,避免回滚段文件无限增长。
3. 事务 ID
每个事务在启动时会被分配一个唯一的事务 ID,事务 ID 是一个单调递增的整数。通过比较事务 ID 的大小,我们可以判断事务的先后顺序。
4. 一致性视图(Read View)
一致性视图是 MVCC 的关键机制之一,它是一个事务在启动时生成的,用于判断当前事务可以看到哪些版本的记录。一致性视图中包含了以下几个重要信息:
-
低水位(trx_ids_min):当前所有活跃事务中最小的事务 ID。
-
高水位(trx_ids_max):生成该视图时系统分配的下一个事务 ID。
-
活跃事务列表(trx_ids):生成该视图时所有活跃事务的事务 ID 列表。
5. 工作流程
MVCC 的工作流程主要涉及读操作和写操作:
读操作
当一个事务要读取某条记录时,会根据记录的 DB_TRX_ID 和一致性视图的信息来判断是否可以看到该记录的当前版本。具体规则如下:
-
如果
DB_TRX_ID < trx_ids_min,即最近修改数据的事务 ID 小于 当前所有活跃事务的最小事务 ID,表示该记录的修改事务在当前事务启动之前已经提交,当前事务可以看到该记录的当前版本。 -
如果
DB_TRX_ID >= trx_ids_max,即最近修改数据的事务 ID 大于等于 生成该视图时系统分配的下一个事务 ID,表示该记录的修改事务在当前事务启动之后才启动,当前事务看不到该记录的当前版本,需要通过DB_ROLL_PTR指针查找旧版本。 -
如果
trx_ids_min <= DB_TRX_ID < trx_ids_max,需要判断DB_TRX_ID是否在活跃事务列表trx_ids中:-
如果在列表中,表示该记录的修改事务在当前事务启动时还未提交,当前事务看不到该记录的当前版本,需要通过
DB_ROLL_PTR指针查找旧版本。 -
如果不在列表中,表示该记录的修改事务在当前事务启动时已经提交,当前事务可以看到该记录的当前版本。
-
写操作
当一个事务要对某条记录进行修改时,会将修改前的记录版本信息存储在回滚段中,并更新记录的 DB_TRX_ID 和 DB_ROLL_PTR 列。具体步骤如下:
-
将修改前的记录版本信息复制到回滚段中。
-
更新记录的
DB_TRX_ID列,将其设置为当前事务的事务 ID。 -
更新记录的
DB_ROLL_PTR指针,使其指向回滚段中存储的旧版本记录。 -
对记录进行实际的修改操作。
通过这种方式,写操作会创建一个新的数据版本,而不会影响其他事务对旧版本的读取。不同事务可以在不同的版本上进行操作,从而实现了读写操作的并发执行。
综上所述,MVCC 通过隐藏列、回滚段、事务 ID 和一致性视图等机制,实现了读写操作的并发执行,提高了数据库的并发性能,同时保证了数据的一致性。不同的事务隔离级别会影响一致性视图的生成和使用方式,从而实现不同程度的数据隔离。
三、对比
MVCC(多版本并发控制)和传统的锁机制都是数据库中用于实现并发控制的重要技术,它们各自具有独特的优缺点,以下是详细对比:
优点对比
MVCC
-
高并发性能
-
MVCC 允许多个事务在不同版本的数据上进行读写操作,避免了大部分情况下的读写锁冲突。读操作可以直接读取数据的历史版本,无需等待写操作释放锁,写操作也不会阻塞读操作,从而显著提高了数据库的并发处理能力。例如,在一个高并发的电商系统中,大量用户同时进行商品信息的查询(读操作)和订单的创建(写操作),MVCC 可以让这些操作并行执行,减少用户的等待时间。
-
-
实现事务隔离
-
能够方便地实现不同的事务隔离级别,如读已提交(Read Committed)和可重复读(Repeatable Read)。通过一致性视图(Read View),事务可以看到特定时间点的数据快照,保证了数据的一致性和隔离性。在可重复读隔离级别下,一个事务在整个生命周期内多次读取同一数据时,会看到相同的结果,避免了不可重复读和部分幻读问题。
-
-
减少死锁概率
-
由于读操作通常不需要加锁,减少了锁的使用,从而降低了死锁发生的可能性。死锁是传统锁机制中常见的问题,当多个事务相互等待对方释放锁时,就会导致死锁的发生。MVCC 的使用使得事务之间的锁竞争减少,系统的稳定性得到提高。
-
传统锁机制
-
强一致性保证
-
传统锁机制可以提供严格的一致性保证,确保在同一时间只有一个事务可以访问或修改数据。在串行化隔离级别下,通过对数据加锁,保证了事务的串行执行,避免了任何并发问题,如脏读、不可重复读和幻读,适用于对数据一致性要求极高的场景,如金融交易系统。
-
-
精确控制并发
-
可以精确地控制事务对数据的访问权限,根据不同的业务需求选择不同类型的锁(如共享锁、排他锁)和加锁粒度(如行锁、表锁)。例如,在某些情况下,需要对整个表进行锁定以确保数据的完整性,传统锁机制可以很方便地实现这一点。
-
缺点对比
MVCC
-
占用额外存储空间
-
为了保存数据的多个版本,MVCC 需要使用回滚段(undo log)来存储旧版本信息,这会占用额外的磁盘空间。随着数据的不断更新和版本的增加,回滚段的空间开销会逐渐增大,需要进行定期的清理和管理。
-
-
回滚段管理开销
-
对回滚段的管理需要额外的系统资源和时间开销。包括回滚段的分配、回收以及过期版本的清理等操作,都会影响数据库的性能。如果回滚段管理不当,可能会导致性能下降或空间浪费。
-
-
不支持完全序列化隔离
-
MVCC 不能完全实现序列化隔离级别,在某些情况下可能会出现幻读问题。虽然在可重复读隔离级别下可以避免大部分幻读,但在极端情况下,仍然可能需要使用额外的锁机制来解决幻读问题。
-
传统锁机制
-
低并发性能
-
传统锁机制会导致读写操作之间的锁竞争,当多个事务同时访问相同的数据时,会出现大量的锁等待现象,降低了数据库的并发性能。例如,一个写操作对数据加了排他锁,其他事务的读操作和写操作都需要等待该锁释放,从而导致系统响应时间变长。
-
-
死锁风险高
-
由于锁的使用,多个事务之间可能会形成循环等待锁的情况,从而导致死锁的发生。死锁的检测和处理需要额外的系统开销,并且会影响事务的正常执行,降低系统的可靠性。
-
-
锁粒度选择困难
-
选择合适的锁粒度是一个难题。如果锁粒度太粗(如表锁),会导致并发性能下降;如果锁粒度太细(如行锁),会增加锁的管理开销和死锁的风险。在实际应用中,需要根据具体的业务场景和数据访问模式来选择合适的锁粒度。
-
相关文章:
MySQL InnoDB引擎 MVCC
MVCC(Multi-Version Concurrency Control)即多版本并发控制,是 MySQL 的 InnoDB 存储引擎实现并发控制的一种重要技术。它在很多情况下避免了加锁操作,从而提高了数据库的并发性能。 一、原理 MVCC 的核心思想是通过保存数据在某…...
深入解析 STM32 GPIO:结构、配置与应用实践
理解 GPIO 的工作原理和配置方法是掌握 STM32 开发的基础,后续的外设(如定时器、ADC、通信接口)都依赖于 GPIO 的正确配置。 目录 一、GPIO 的基本概念 二、GPIO 的主要功能 三、GPIO 的内部结构 四、GPIO 的工作模式 1. 输入模式 2. 输…...
【Elasticsearch】管道聚合
管道聚合就是在已有聚合结果之上在进行聚合,管道聚合是针对于聚合的聚合 在 Elasticsearch 中,管道聚合(Pipeline Aggregations)是一种特殊的聚合类型,用于对其他聚合的结果进行进一步的计算和处理,而不是直…...
Python的那些事第十八篇:框架与算法应用研究,人工智能与机器学习
人工智能与机器学习:框架与算法应用研究 摘要 本文深入探讨了人工智能与机器学习领域的核心框架和技术,包括TensorFlow、PyTorch和Scikit-learn库。文章首先介绍了TensorFlow和PyTorch的安装与配置方法,详细阐述了它们的基础概念,…...
【大数据安全分析】为什么要用大数据技术进行安全分析?
在当今数字化浪潮的推动下,安全运营领域犹如一片广袤且复杂的战场。由于其涵盖范围极为宽泛,为了能更深入、精准地探讨相关内容,将目光聚焦于大数据安全分析方向显得尤为必要。一方面,大数据安全分析在安全运营领域占据着举足轻重的地位;另一方面,倘若自身对该领域较为熟…...
java微服务常用技术
Spring Cloud Alibaba 1 系统架构演进 随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。 1.1 单体架构 早期的软件系统通常是基于单体应用架构设计的,也就是将整个系统作为一个单一的、可执行的应用程序来构建和维护…...
【Qt 常用控件】多元素控件(QListWidget、QTabelWidgt、QTreeWidget)
**View和**Widget的区别? **View的实现更底层,**Widget是基于**View封装实现的更易用的类型。 **View使用MVC结构 MVC是软件开发中 经典的 软件结构 组织形式,软件设计模式。 M(model)模型。管理应用程序的核心数据和…...
ubuntu文件同步
1. 使用 rsync 同步文件 rsync 是一个常用的文件同步工具,可以在本地或远程系统之间同步文件和目录。 基本用法: rsync -avz /源目录/ 目标目录/-a:归档模式,保留文件属性。-v:显示详细输出。-z:压缩传输…...
解决VsCode的 Vetur 插件has no default export Vetur问题
文章目录 前言1.问题2. 原因3. 解决其他 前言 提示: 1.问题 Cannot find module ‘ant-design-vue’. Did you mean to set the ‘moduleResolution’ option to ‘node’, or to add aliases to the ‘paths’ option? Module ‘“/xxx/xxx/xxx/xxx/xxx/src/vie…...
DeepSeek本地部署详细指南
DeepSeek本地部署详细指南 随着人工智能技术的飞速发展,本地部署大模型的需求也日益增加。DeepSeek作为一款开源且性能强大的大语言模型,提供了灵活的本地部署方案,让用户能够在本地环境中高效运行模型,同时保护数据隐私。以下是…...
DNS污染:网络世界的“隐形劫持”与防御
在互联网的底层架构中,DNS(域名系统)如同数字世界的“导航员”,将用户输入的域名翻译成机器可读的IP地址。然而,DNS污染(DNS Poisoning)正像一场无声的“地址篡改”危机,威胁着全球网…...
AF3 superimpose函数解读
AlphaFold3 superimpose函数通过使用SVD最小化RMSD,将坐标叠加到参考上,在蛋白质结构预测中用于比较预测结构与真实结构的相似性。 源代码: from src.utils.geometry.alignment import weighted_rigid_align from src.utils.geometry.vect…...
python制作自己的一款Markdowm格式消除工具
01 引言 在日常使用 Markdown 编写文档时,我们有时会需要将 Markdown 格式的文本转换为纯文本,去除其中的各种标记符号,如标题符号、列表符号、代码块标记等。手动去除这些标记不仅效率低下,还容易出错。本文将介绍如何使用 Pyt…...
【C#零基础从入门到精通】(三)——C#变量和数据类型详解
【C#零基础从入门到精通】(三)——C#变量和数据类型详解 数据类型 在 C# 中,数据类型是对数据进行分类的方式,它定义了变量可以存储的数据的种类、范围以及可以对这些数据执行的操作。C# 的数据类型主要分为值类型、引用类型和指针类型(指针类型通常在不安全代码中使用),…...
如何从头训练大语言模型: A simple technical report
今天来快速捋一下路线,写个简短的technical report,更多是原理介绍性的。按我个人理解,从最简单的部分开始,逐步过渡到最繁复的环节: 模型架构-> Pretrain -> Post-Train -> Infra -> 数据侧。再掺杂一些杂项…...
gitlab无法登录问题
在我第一次安装gitlab的时候发现登录页面是 正常的页面应该是 这种情况的主要原因是不是第一次登录,所以我们要找到原先的密码 解决方式: [rootgitlab ~]# vim /etc/gitlab/initial_root_password# WARNING: This value is valid only in the followin…...
食品饮料生产瓶颈?富唯智能协作机器人来 “破壁”
在食品和饮料行业的发展进程中,诸多生产瓶颈如重复性劳动负担、复杂环境作业难题、季节性产能波动等,长期制约着企业的高效运营与进一步发展。如今,富唯智能协作机器人的出现,为这些难题提供了完美的解决方案,正逐步改…...
Python 实现 macOS 系统代理的设置
设置 SOCKS 代理 在 macOS 系统中,可以通过 networksetup 工具来设置 SOCKS 代理。以下是 Python 实现的方法: 使用 networksetup 设置 SOCKS 代理 import subprocessdef set_socks_proxy(server, port):"""设置 macOS 系统的 SOCKS 代理…...
深度学习之神经网络框架搭建及模型优化
神经网络框架搭建及模型优化 目录 神经网络框架搭建及模型优化1 数据及配置1.1 配置1.2 数据1.3 函数导入1.4 数据函数1.5 数据打包 2 神经网络框架搭建2.1 框架确认2.2 函数搭建2.3 框架上传 3 模型优化3.1 函数理解3.2 训练模型和测试模型代码 4 最终代码测试4.1 SGD优化算法…...
excel 日期转换
需求如下: 在excel 里面输入一个4515,4表示年份,2024年,51表示该年的51周,5表示日,周日用1表示,周一用2表示,以此类推,需要转换为年份/月份/日期 若想用公式来实现这一转换&#x…...
Awtk 如何添加开机画面
场景 我们知道在工程中,Ui是一个线程,并且需要一直存在,当我们使用的开机画面在这个线程开启就直接展示的时候,因为awtk的界面是window_open入栈的,即首次打开的窗口会记录在top,往后的窗口会依次往后存放&…...
【设计模式】【行为型模式】命令模式(Command)
👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD 🔥 2025本人正在沉淀中… 博客更新速度 📫 欢迎V: flzjcsg2,我们共同讨论Java深渊的奥秘 …...
C++模拟实现AVL树
目录 1.文章概括 2.AVL树概念 3.AVL树的性质 4.AVL树的插入 5.旋转控制 1.左单旋 2. 右单旋 3.左右双旋 4.右左双旋 6.全部代码 1.文章概括 本文适合理解平衡二叉树的读者阅读,因为AVL树是平衡二叉树的一种优化,其大部分实现逻辑与平衡二叉树是…...
推荐算法实践:movielens数据集
MovieLens 数据集介绍 MovieLens 数据集是由明尼苏达大学的GroupLens研究小组维护的一个广泛使用的电影评分数据集,主要用于推荐系统的研究。该数据集包含用户对电影的评分、标签以及其他相关信息,是电影推荐系统开发与研究的常用数据源。 数据集版本 …...
dynamic_cast和static_cast和const_cast
dynamic_cast 在 C 中的作用 dynamic_cast 是 C 运行时类型转换(RTTI, Run-Time Type Identification)的一部分,主要用于: 安全的多态类型转换检查类型的有效性向下转换(Downcasting)跨类层次的指针或引用…...
React进行路由跳转的方法汇总
在 React 中进行路由跳转有多种方法,具体取决于你使用的路由库和版本。以下是常见的路由跳转方法汇总,主要基于 react-router-dom 库。 1. 使用 useNavigate 钩子(适用于 react-router-dom v6) useNavigate 是 react-router-dom…...
python卷积神经网络人脸识别示例实现详解
目录 一、准备 1)使用pytorch 2)安装pytorch 3)准备训练和测试资源 二、卷积神经网络的基本结构 三、代码实现 1)导入库 2)数据预处理 3)加载数据 4)构建一个卷积神经网络 5࿰…...
以Unity6.0为例,如何在Unity中开启DLSS功能
DLSS DLSS(NVIDIA 深度学习超级采样):NVIDIA DLSS 是一套由 GeForce RTX™ Tensor Core 提供支持的神经渲染技术,可提高帧率,同时提供可与原生分辨率相媲美的清晰、高质量图像。目前最新突破DLSS 4 带来了新的多帧…...
CSDN 大模型 笔记
AI 3大范式:计算 发发 交互 L1 生成代码 复制到IDEA (22年12-23年6,7月份) L2 部分自动编程 定义class 设计interface 让其填充实现 (23年7,8月份) L3 通用任务 CRUD (24年) L4 高度自动编程 通用领域专有任务…...
Flink怎么保证Exactly - Once 语义
Exactly - Once 语义是消息处理领域中的一种严格数据处理语义,指每条数据都只会被精确消费和处理一次,既不会丢失,也不会重复。 以下从消息传递语义对比、实现方式、应用场景等方面详细介绍: 与其他消息传递语义对比 在消息传递…...
