MySQL的并发控制与MVCC机制深度解析
目录
- 1. MySQL中的并发问题
- 2. 数据库的隔离级别
- 3. MVCC(多版本并发控制)机制
- 3.1 MVCC的实现原理
- 3.2 Read View详解
- 3.3 当前读与快照读
- 4. MVCC在不同隔离级别下的工作方式
- 5. MVCC解决幻读问题
- 6. MVCC的优缺点
- 优点:
- 缺点:
- 7. MVCC在实际应用中的注意事项
1. MySQL中的并发问题
在多用户数据库系统中,并发操作是不可避免的。然而,并发操作可能会导致一些问题,主要包括:
-
脏读:一个事务读取了另一个未提交事务修改过的数据:
A事务读取B事务修改后的数据返回,然而B事务发生了回滚

- 不可重复读:在同一事务内,多次读取同一数据返回的结果有所不同:
A事务多次读取同一个数据,B事务修改了该数据,A事务读到的数据不一样

- 幻读:在同一事务内,多次查询返回的结果集不一致:
A事务多次读取某些数据(比如查询表的数据总数),B事务插入或者删除了数据,A读取的数据数量发生了变更,像幻觉一样

注意区分幻读和不可重复读
为了解决这些问题,数据库系统引入了事务隔离级别的概念。
2. 数据库的隔离级别
SQL标准定义了四种隔离级别,从低到高分别是:
- 读未提交(Read Uncommitted)
- 读已提交(Read Committed)
- 可重复读(Repeatable Read)
- 串行化(Serializable)
让我们用一个图表来展示这些隔离级别如何解决并发问题:

MySQL的InnoDB存储引擎默认使用**可重复读(Repeatable Read)**隔离级别。他引入了MVCC来解决这个不可重复读的问题(读已提交也有MVCC,两者之间只是创建快照的时机不同,后面再提)
3. MVCC(多版本并发控制)机制
MVCC是MySQL InnoDB存储引擎用于提高并发性能的一种机制。它的核心思想是:
保存数据在某个时间点的快照,形成一个版本链,使得事务可以看到在事务开始时数据的一致性视图。
3.1 MVCC的实现原理
InnoDB的MVCC主要通过以下几个部分来实现:
-
隐藏列:每行数据都有两个隐藏列
DB_TRX_ID:最后一次插入或更新该行的事务IDDB_ROLL_PTR:回滚指针,指向该行的上一个版本(存储在undo log中)
-
Undo Log:保存了数据被修改前的旧值,用于回滚和MVCC的数据读取。可以认为undo log存储数据的历史版本,通过指针会形成一个版本链。
-
Read View:事务进行快照读操作时产生的读视图,用于判断当前事务能够看到哪个版本的数据。
让我们用一个图表来展示MVCC的基本结构:

3.2 Read View详解
Read View是MVCC实现的核心,它包含以下重要信息:
m_ids:活跃事务列表,在生成Read View时活跃的读写事务ID列表,就是记录当前还未提交的事务列表m_low_limit_id/(m_min_limit_id):活跃事务的最小事务id,就是活跃列表的最小值m_up_limit_id/(m_max_limit_id):下一个事务应该被分配的事务idm_creator_trx_id:生成该Read View的事务ID
注意:事务id是递增分配的
当一个事务要读取一行数据时,InnoDB会将该行的DB_TRX_ID(前面提到的,表示这行数据最近一次发生修改的事务id)与Read View中的信息进行比较,以决定是否可以看到该版本的数据:
1. DB_TRX_ID == m_creator_trx_id:当前读取的事务就是创建快照读的事务,说明就是该事务最近修改了这条数据,因此是可读的;
2. DB_TRX_ID < m_low_limit_id:当这条数据最新更改的事务id小于最小活跃事务id,就说明该事务id是已经提交的事务id,该条数据就可读
3. DB_TRX_ID >= m_up_limit_id:这条数据的最新记录是在快照建立之后执行的,显然属于不可读,根据回滚指针找到合适的历史版本数据进行返回
4. m_low_limit_id < DB_TRX_ID < m_up_limit_id:这条数据最新更改的事务id在最小活跃事务id和最大事务id(下一次分配的事务id)之间,那就需要去扫描活跃事务列表,判断是否有这个id存在:
- 有就说明该数据还没有被提交是不可读的,那么他就会根据DB_ROLL_PTR去找到该数据的历史版本,同样会进行判断,直至找到符合可读条件的数据返回
- 如果列表没有就表明该事务已经被提交了,就是可读的

3.3 当前读与快照读
在InnoDB中,我们有两种读取数据的方式:
-
当前读(Current Read):
- 读取的是记录的最新版本
- 会对读取的记录进行加锁
- 常见的当前读操作:
SELECT ... FOR UPDATE,SELECT ... LOCK IN SHARE MODE,UPDATE, DELETE等
-
快照读(Snapshot Read):
- 读取的是记录的快照版本
- 不会对读取的记录进行加锁
- 常见的快照读操作:不带锁的SELECT
让我们用一个图表来说明当前读和快照读的区别:

4. MVCC在不同隔离级别下的工作方式
MVCC主要工作在读已提交和可重复读这两个隔离级别下:
-
读已提交:
- 每次读取数据前都会生成一个新的Read View
- 能看到其他事务已经提交的修改
-
可重复读:
- 在事务开始时生成一个Read View,并在整个事务过程中使用这个Read View
- 保证在同一事务中多次读取数据时结果一致
让我们用一个例子来说明这两种隔离级别下MVCC的工作方式:

5. MVCC解决幻读问题
虽然MVCC可以有效解决不可重复读问题,但对于幻读,它只能提供部分解决方案。在可重复读隔离级别下,MVCC可以防止"快照读"出现幻读,但无法完全阻止"当前读"的幻读问题。
为了进一步解决幻读问题,InnoDB引入了Next-Key Lock(临键锁)机制,它是记录锁(Record Lock)和间隙锁(Gap Lock)的组合。

Next-Key Lock不仅锁定查询涉及的索引记录,还锁定这些记录之间的间隙,有效防止了其他事务在查询范围内插入新记录,从而解决了幻读问题。
6. MVCC的优缺点
优点:
- 提高并发性:允许读写并发,读操作不会阻塞写操作,写操作也不会阻塞读操作。
- 解决一致性问题:提供了一致性的数据视图,避免了脏读和不可重复读问题。
- 降低锁竞争:通过版本链和快照读,减少了锁的使用范围,从而提高了系统的整体性能。
- 支持时间点查询:可以查询某个时间点的历史数据,对于某些应用场景非常有用。
缺点:
- 存储开销:需要额外的存储空间来保存多个版本的数据。
- 复杂性:实现和维护MVCC机制相对复杂,增加了数据库系统的复杂度。
- 清理问题:需要定期清理无用的历史版本,否则可能导致存储空间的浪费。
- 事务大小限制:长事务可能会导致版本链过长,影响性能。
7. MVCC在实际应用中的注意事项
- 合理设置隔离级别:根据应用需求选择适当的隔离级别,避免过度使用高隔离级别带来的性能开销。
- 控制事务大小:尽量使用短事务,避免长事务导致的版本链过长问题。
- 定期维护:对于频繁更新的表,需要定期进行维护操作,如优化表结构、清理无用的历史版本等。
- 索引优化:合理设计索引可以提高MVCC的效率,减少不必要的版本链遍历。
- 监控与调优:定期监控系统性能,关注MVCC相关的指标,如undo log的大小、长事务的数量等,及时进行调优。
相关文章:
MySQL的并发控制与MVCC机制深度解析
目录 1. MySQL中的并发问题2. 数据库的隔离级别3. MVCC(多版本并发控制)机制3.1 MVCC的实现原理3.2 Read View详解3.3 当前读与快照读 4. MVCC在不同隔离级别下的工作方式5. MVCC解决幻读问题6. MVCC的优缺点优点:缺点: 7. MVCC在…...
Qt编译MySQL数据库驱动
目录 Qt编译MySQL数据库驱动 测试程序 Qt编译MySQL数据库驱动 (1)先找到MySQL安装路径以及Qt安装路径 C:\Program Files\MySQL\MySQL Server 8.0 D:\qt\5.12.12 (2)在D:\qt\5.12.12\Src\qtbase\src\plugins\sqldrivers\mysql下…...
uniapp地址类 方法
关于点击没反应 manifest.json 检查是否添加了对应的权限 /* 小程序特有相关 */"mp-weixin" : {"appid" : "wxc481f10754f1d9df","setting" : {"urlCheck" : false,"es6" : true,"postcss" : true,&qu…...
使用Idea自带的git功能进行分支合并
文章目录 1.背景描述2.分支切换3.分支合并的具体操作4.将在local环境下,从dev合并到qas分支上的代码,推送到远端 1.背景描述 目前在开发的当前项目有四个分支,master(主分支)、pre(预生产分支)、qas(测试分支)、dev(开发分支); …...
酷盾安全:Edge SCDN边缘安全内容分发网络
在当今数字化迅猛发展的时代,互联网内容分发的高效与安全成为了企业不可忽视的重要课题。为了满足这一需求,酷盾安全推出了创新的Edge Secure Content Delivery Network(Edge Scdn)解决方案,它不仅融合了分布式DDoS防护…...
H5 中 van-popup 的使用以及题目的切换
H5 中 van-popup 的使用以及题目的切换 在移动端开发中,弹窗组件是一个常见的需求。vant 是一个轻量、可靠的移动端 Vue 组件库,其中的 van-popup 组件可以方便地实现弹窗效果。本文将介绍如何使用 van-popup 实现题目详情的弹窗展示,并实现…...
Liinux下VMware Workstation Pro的安装,建议安装最新版本17.61
建议安装最新版本17.61,否则可能有兼容性问题 下载VMware Workstation安装软件 从官网网站下载 https://support.broadcom.com/group/ecx/productdownloads?subfamilyVMwareWorkstationPro 选择所需版本 现在最新版本是17.61,否则可能有兼容性问题…...
WebRTC服务质量(05)- 重传机制(02) NACK判断丢包
WebRTC服务质量(01)- Qos概述 WebRTC服务质量(02)- RTP协议 WebRTC服务质量(03)- RTCP协议 WebRTC服务质量(04)- 重传机制(01) RTX NACK概述 WebRTC服务质量(…...
修改ubuntu apt 源及apt 使用
视频教程:修改ubuntu apt 源和apt 使用方法_哔哩哔哩_bilibili 1 修改apt源 1.1 获取阿里云ubuntu apt 源 https://developer.aliyun.com/mirror/ubuntu?spma2c6h.13651102.0.0.3e221b11mqqLBC 1.2 修改apt 源 vim /etc/apt/sources.list deb https://mirrors.aliyun.com/ub…...
深入解析 `DataFrame.groupby` 和 `agg` 的用法及使用场景
深入解析 DataFrame.groupby 和 agg 的用法及使用场景 1. groupby 的基本用法语法:示例: 2. agg 的基本用法语法:示例: 3. first、sum、lambda 的用法3.1 first示例: 3.2 sum示例: 3.3 lambda示例ÿ…...
MySQL 的锁
MySQL有哪些锁?各种锁的作用与使用场景全局锁表级锁表锁元素锁意向锁AUTO-INC 锁 行级锁记录锁间隙锁临键锁 其他共享锁排他锁乐观锁悲观锁 MySQL有哪些锁? 全局锁表级锁 a. 表锁 b. 元素锁 c. 意向锁 d. AUTO-INC 锁行级锁 a. 记录锁 b. 间隙锁 c. 临键锁 各种锁的作用与使…...
二、使用langchain搭建RAG:金融问答机器人--数据清洗和切片
选择金融领域的专业文档作为源文件 这里选择 《博金大模型挑战赛-金融千问14b数据集》,这个数据集包含若干公司的年报,我们将利用这个年报搭建金融问答机器人。 具体下载地址 这里 git clone https://www.modelscope.cn/datasets/BJQW14B/bs_challenge_…...
【Linux】-- linux 配置用户免密登录本机
比如我们要配置用户 app_tom 免密登录本机(SSH 登录自己机器时无需输入密码),你可以按照以下步骤操作: 步骤 1:切换到 app_tom 用户 首先,确保你已经以 app_tom 用户登录,或者切换到该用户&…...
泷羽sec学习打卡-brupsuite8伪造IP和爬虫审计
声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-Brup-FaskIP 伪造IP配置环境brupsuite导入配置1、扩展中先配置python环境2、安…...
【uniapp蓝牙】基于native.js链接ble和非ble蓝牙
【uniapp蓝牙】基于native.js链接ble和非ble蓝牙 uniapp不是仅支持低功耗蓝牙(基础蓝牙通讯不支持),有些可能需要基础蓝牙。我现在同步我的手机蓝牙列表低功耗,基础蓝牙都支持 /*** author wzj* 通用蓝牙模块封装* 搜索 ble 和非…...
.NET Core 各版本特点、差异及适用场景详解
随着 .NET Core 的不断发展,微软推出了一系列版本来满足不同场景下的开发需求。这些版本随着时间的推移逐渐演变为统一的 .NET 平台(从 .NET 5 开始)。本文将详细说明每个版本的特点、差异以及适用场景,帮助开发者更好地选择和使用…...
Linux中自动检测并定时关闭KDialog程序
自动检测并关闭对话框的程序示例 创建并打开KDialog的脚本自动检测并定时关闭KDialog的脚本 创建并打开KDialog的脚本 #!/bin/bash kdialog --msgbox "demo"自动检测并定时关闭KDialog的脚本 #!/bin/bash# Continuously check for kdialog dialog while true; do# …...
CSS学习记录12
CSS浮动 CSSfloat属性规定元素如何浮动 CSSclear属性规定哪些元素可以在清除的元素旁边以及在哪一侧浮动。 float属性 float属性用于定位和格式化内容,例如让图像向左浮动到容器的文本那里。 float属性可以设置以下值之一: left - 元素浮动到其容器…...
【Java基础面试题016】JavaObject类中有什么主要方法,作用是什么?
equals() 作用:用于比较两个对象是否相等。默认实现比较对象的内存地址,即判断两个引用是否指向同一个对象 使用:通常会重写此方法来比较对象的内容 hashCode() 作用:返回对象的哈希值,用整数表示对象。 使用&…...
实践环境-docker安装mysql8.0.40步骤
一、docker安装mysql 8.0.40版本 1、检索镜像版本 docker search mysql:8.0.40 NAME DESCRIPTION STARS OFFICIAL mysql MySQL is a widely used, open-source relation… …...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...
