当前位置: 首页 > article >正文

数据库的MVCC机制详解

MVCC(Multi-Version Concurrency Control,多版本并发控制)是数据库系统中常用的并发控制机制,它允许数据库在同一时间点保存数据的多个版本,从而实现非阻塞的读操作,提高并发性能。

MVCC的核心思想是:

  • 读不阻塞写,写不阻塞读
  • 每个事务看到的是数据库在事务开始时的一致性快照
  • 通过版本链实现数据的多版本存储

为什么需要MVCC?

我们知道数据库有行锁,表锁来保证数据的安全性,但同时也有可能导致阻塞(响应缓慢)和死锁(不可用)。而MVCC正是解决这些问题的机制。MVCC通过保存数据的历史版本来避免读写冲突,这样读操作不会阻塞写操作,写操作也不会阻塞读操作。

MVCC主要功能有哪些?

1) 数据版本管理

2) 事务隔离级别控制 

3) 并发冲突检测与解决

4) 数据一致性维护

1) 数据版本管理

数据库为每一行数据会维护一个版本链,其中有两个主要的信息,事务id与回滚指针。

回滚指针指向的是回滚日志

  • 每次修改数据时(如 INSERT/UPDATE/DELETE),数据库会记录旧数据的 undo log。

  • Undo log 按事务隔离,形成版本链:

    • INSERT 操作:记录插入数据的 undo log(用于回滚时删除)。

    • UPDATE/DELETE 操作:记录旧数据的完整拷贝(用于构建历史版本)。

版本链的构建流程

以一行数据为例

  1. 初始状态
    数据行 id=1,值 value=A,事务ID txid=100,回滚指针指向 NULL

    | id=1 | value=A | DB_TRX_ID=100 | DB_ROLL_PTR=NULL |
  2. 事务 txid=200 更新值

    • 生成新版本数据 value=B,更新 DB_TRX_ID=200

    • 将旧版本数据 value=A 写入 undo log。

    • 新版本的回滚指针指向旧版本的 undo log 地址。

    新版本数据:| id=1 | value=B | DB_TRX_ID=200 | DB_ROLL_PTR=0x123(指向 undo log 中的旧版本)|
  3. 事务 txid=300 再次更新值

    • 生成新版本 value=C,更新 DB_TRX_ID=300

    • 旧版本 value=B 写入 undo log。

    • 版本链形成:C ← B ← A(通过回滚指针链接)。

2) 事务隔离级别控制 

可见性规则(判断数据是否可见)

事务读取数据时,需根据 快照版本 和 事务ID 判断哪个版本对其可见。规则如下:

1. Read View(读视图)

每个事务在首次查询时会生成一个 Read View,包含:

  • 活跃事务列表:当前未提交的事务ID集合。

  • 最小活跃事务ID(low_limit_id):活跃事务中的最小ID。

  • 最大事务ID(up_limit_id):下一个即将分配的事务ID(即当前最大ID+1)。

2. 可见性判断逻辑

对数据行的每个版本,检查其 DB_TRX_ID

  1. 如果 DB_TRX_ID < low_limit_id 且不在活跃事务列表中 → 可见(该版本在事务开始时已提交)。

  2. 如果 DB_TRX_ID >= up_limit_id → 不可见该版本在事务开始后创建)。

  3. 如果 DB_TRX_ID 在活跃事务列表中 → 不可见该版本的事务尚未提交)。

  4. 其他情况需进一步判断(如版本是否被删除)。

不同隔离级别实现
1. 读已提交(Read Committed)
  • 每次查询生成新的 Read View。

  • 能看到其他事务 已提交的最新修改

2. 可重复读(Repeatable Read)
  • 事务开始时生成一次 Read View,后续查询沿用该视图。

  • 始终看到事务开始时的数据快照,其他事务的修改不可见(解决不可重复读)。

3. 幻读的特殊处理
  • MySQL 通过 Next-Key Lock(间隙锁+行锁)解决幻读问题。

  • PostgreSQL 依赖快照隔离,但严格的可串行化隔离级别需要显式锁。

3) 并发冲突检测与解决

常见的并发冲突类型
  1. 写-写冲突(Lost Update)
    两个事务同时修改同一数据,后提交的事务覆盖前一个事务的结果(如库存扣减场景)。

  2. 读-写冲突(Dirty Read/Unrepeatable Read)
    事务 A 读取数据后,事务 B 修改了该数据,导致事务 A 的后续操作不一致。

  3. 幻读(Phantom Read)
    事务 A 读取某范围数据时,事务 B 插入或删除了符合该范围的数据,导致事务 A 两次读取结果不一致。

冲突解决策略
  1. 版本链与回滚

    • 当检测到冲突时(如写-写冲突),MVCC通过版本链回溯到可用的旧版本,确保读操作不受影响。
    • 例如,InnoDB的undo log存储旧版本数据,供回滚和一致性读使用
  2. 垃圾回收机制

    • 定期清理无效版本(如PostgreSQL的VACUUM、MySQL的purge线程)。
    • 通过检查xmax状态(已提交或未提交)和事务活跃状态,删除过期版本

相关文章:

数据库的MVCC机制详解

MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09;是数据库系统中常用的并发控制机制&#xff0c;它允许数据库在同一时间点保存数据的多个版本&#xff0c;从而实现非阻塞的读操作&#xff0c;提高并发性能。 MVCC的核心思想是&…...

C++初阶-C++入门基础

目录 ​编辑 1.C的简介 1.1C的产生和发展 1.2C的参考文档 1.3C优势和难度 1.4C学习的建议 2.C的第一个程序 2.1打印Hello world 2.2头文件 2.3namespace命名空间 2.4&#xff1a;&#xff1a;作用域限定符 2.5namespace的延伸 2.6C的输入输出 3.总结 1.C的简介 …...

关于量化交易在拉盘砸盘方面应用的部分思考

关于“砸盘”的深层解析与操盘逻辑 ​​一、砸盘的本质与市场含义​​ ​​砸盘​​指通过集中抛售大量筹码导致价格快速下跌的行为&#xff0c;其核心目标是​​制造恐慌、清洗浮筹或实现利益再分配​​。不同场景下的砸盘含义不同&#xff1a; ​​主动砸盘&#xff08;操控…...

idea手动创建resources文件夹

有时maven没有构建成功可能造成&#xff0c;resources文件夹不创建的现象 此时我们可以手动创建 手动创建...

第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组题目试做(中)【本期题目:回文数组,挖矿】

OK&#xff0c;继续写我们的第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组题目&#xff0c;后面的题目比较麻烦了&#xff0c;所以我们再分两期讲。 这一期的题有 &#xff1a; 回文数组&#xff0c;挖矿 文章目录 回文数组基本思路第一步&#xff0c;获取半个数组每个数需要…...

Qt动画 QAbstractAnimation

文章目录 简介QVariantAnimation 数值动画QPropertyAnimation 属性动画 QAnimationGroup 一组动画QParallelAnimationGroup 并行动画组QSequentialAnimationGroup 串行动画组 简介 QAbstractAnimation 是所有 Qt 动画的基类。 该类定义了所有动画应该都会有的功能函数。 要想实…...

SpringMvc的请求-获得请求参数

客户端请求参数的格式是: namevalue&namevalue..… 服务器端要获得请求的参数&#xff0c;有时还需要进行数据的封装&#xff0c;SpringMVC可以接收如下类型的参数: 基本类型参数 POJO类型参数 数组类型参数 集合类型参数 获得基本类型参数 Controller中的业务方法…...

flutter开发音乐APP(前提准备)

1、项目的一些环境&#xff1a; 2、接口文档&#xff1a; 酷狗音乐 NodeJS 版 API 3、接口数据结构化 Instantly parse JSON in any language | quicktype UI样式借鉴参考&#xff1a; Coffee-Expert/Apple-Music-New-UI: Apple Music Clone on Flutter, with redesigned UI…...

使用docker搭建redis镜像时云服务器无法访问到国外的docker官网时如何解决

下载redis镜像 docker redis:版本号 此时截图中无法访问到国外的docker官网 解决方案&#xff1a; 通过更换镜像源来正常下载redis镜像 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<EOF {"registry-mirrors": ["https://docker.1…...

双引擎驱动:解密音视频体验的QoS技术底座与QoE感官革命

QoS 定义&#xff1a;QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;衡量音视频传输技术层面的性能表现&#xff0c;聚焦网络传输和系统处理能力&#xff0c;通过客观指标量化服务质量。核心指标 码率/带宽&#xff1a;数据传输速率上限&#xff0c;直接…...

Qt之QNetworkInterface

简介 用于表示网络接口&#xff08;即网卡&#xff09;信息 常用接口 static QList<QNetworkInterface> allInterfaces(); static QList<QHostAddress> allAddresses(); QList<QNetworkAddressEntry> addressEntries() const;接口类型 用枚举InterfaceTy…...

pom导包成功,但是就是无法使用相关类,同时报错:Library:Maven ‘xxx‘ has broken path

开发环境&#xff1a;Intellij 2023 一、问题记录 在maven工程的pom文件导入如下某一依赖(JGit)。没有显示导包的错误&#xff0c;同时在maven仓库里面找到对应的包是正常下载到相应jar的。 但是就是无法引入相关的类。打开Project Structure&#xff0c;在Dependencies中发现…...

大数据技术之Scala

Spark运行架构核心是一个计算引擎 核心组件 1. Driver&#xff08;驱动器&#xff09; 角色&#xff1a;Spark作业的“大脑”&#xff0c;负责解析用户代码、生成任务并调度执行。 功能&#xff1a; 将用户程序转换为作业&#xff08;Job&#xff09;。 …...

LeetCode刷题常见的Java排序

1. 字符串排序(字母排序) 首先,你的代码实现了根据字母表顺序对字符串中的字母进行排序,忽略了大小写并且保留了非字母字符的位置。关键点是: 提取和排序字母:通过 Character.isLetter() 判断是否为字母,并利用 Character.toLowerCase() 来忽略大小写进行排序。保留非字…...

mysql的下载和安装2025.4.8

mysql下载和安装 MySQL的下载网址&#xff1a; https://www.mysql.com/downloads/ 点击进入Windows版本下载&#xff1a;我们可以选择需要的MySQL版本以及所需的操作系统&#xff0c;这里选择离线安装&#xff1a; 注意&#xff1a;MySQL 8.0 是带有 MySQL Installer 的最后一…...

QML Loader:延迟加载与动态切换

目录 引言相关阅读工程结构LoaderDelay.qml - 延迟加载实现完整代码HeavyComponent.qml代码解析运行效果 LoaderSwitch.qml - 动态切换组件完整代码代码解析运行效果 Main.qml - 主界面实现完整代码主界面结构代码解析 总结下载链接 引言 QML的Loader组件提供了一种强大的机制…...

Python和MicroPython的解释器区别

Python和MicroPython的解释器不是同一个&#xff0c;它们在设计目标、实现方式和运行环境上都有显著的区别。以下是它们的主要区别&#xff1a; 1. 底层实现 Python解释器&#xff08;CPython&#xff09;&#xff1a; Python的标准解释器是CPython&#xff08;C语言实现的Pyt…...

Git 的进阶功能和技巧

1、分支的概念和使用 1.1、什么是分支&#xff1f; 分支&#xff08;Branch&#xff09;是在版本控制中非常重要的概念。几乎所有版本控制系统都支持某种形式的分支。在 Git 中&#xff0c;分支是 Git 强大功能之一&#xff0c;它允许我们从主开发线分离出来&#xff0c;在不…...

解析HiveQL的ALTER TABLE ADD/REPLACE COLUMNS语句

阅读以下ALTER TABLE的ADD/REPLACE COLUMNS语句的语法,用C#编写解析函数,一个一个字符解析,所有关键字不区分大小写,一个或多个空格、Tab和换行的组合都可以是关键词之间的分隔,表名和字段名可能包含空格和Tab,语句中可以用`包裹表名和字段名,解析以下HiveQL语句在所有可…...

Spark Core编程

一 Spark 运行架构 1 运行架构 定义 Spark 框架的核心是一个计算引擎&#xff0c;整体来说&#xff0c;它采用了标准 master-slave 的结构 如图所示 2 核心组件 Spark 框架有两个核心组件: 1)Driver 2)Spark 驱动器节点&#xff08;用于执行 Spark 任务中的 main 方法&…...

在Ubuntu内网环境中为Gogs配置HTTPS访问(通过Apache反向代理使用IP地址)

一、准备工作 确保已安装Gogs并运行在HTTP模式(默认端口3000) 确认服务器内网IP地址(如192.168.1.100) 二、安装Apache和必要模块 sudo apt update sudo apt install apache2 -y sudo a2enmod ssl proxy proxy_http rewrite headers 三、创建SSL证书 1. 创建证书存储目录…...

Kafka和RocketMQ相比有什么区别?那个更好用?

Kafka和RocketMQ相比有什么区别?那个更好用? Kafka 和 RocketMQ 都是广泛使用的消息队列系统&#xff0c;它们有很多相似之处&#xff0c;但也有一些关键的区别。具体选择哪个更好用&#xff0c;要根据你的应用场景和需求来决定。以下是它们之间的主要区别&#xff1a; 1. …...

无人机装调与测试

文章目录 前言一、无人机基本常识/预备知识&#xff08;一&#xff09;无人机飞行原理无人机硬件组成/各组件作用1.飞控2.GPS3.接收机4.电流计5.电调6.电机7.电池8.螺旋桨9.UBEC&#xff08;稳压模块&#xff09; &#xff08;二&#xff09;飞控硬件简介&#xff08;三&#x…...

JavaScript Hook JSON.stringify和JSON.parse:逆向与修改实战指南

在JavaScript逆向工程中&#xff0c;Hook JSON.stringify和JSON.parse方法是一种重要的技术&#xff0c;可以用来捕获、修改或分析JSON数据的序列化和反序列化过程。本文将结合具体案例&#xff0c;详细讲解如何实现这些方法的Hook操作。 一、Hook JSON.stringify和JSON.parse…...

【图书管理系统】全栈开发图书管理系统获取图书列表接口(后端:计算图书页数、查询当前页展示的书籍)

图书列表 实现服务器代码(计算图书总数量查询当前页需要展示的书籍) 后端响应时&#xff0c;需要响应给前端的数据 records&#xff1a;第 pageNum 页要展示的图书有哪些&#xff08;存储到List集合中&#xff09;total&#xff1a;计算一共有多少本书&#xff08;用于告诉前…...

正则表达式补充——python

简介 本章是对前面正则表达式的补充。 一、复杂的查找替换等任务 content 张三是脑卒中病 李四&#xff0c;是高血脂 苏齐&#xff0c;是肺结核病 六六&#xff0c;是血血血血import re p re.compile(r...病) for one in p.findall(content):print(one) 运行结果&#xf…...

Kotlin日常使用函数记录

文章目录 前言字符串集合1.两个集合的差集2.集合转数组2.1.集合转基本数据类型数组2.2.集合转对象数组 Map1.合并Map1.1.使用 操作符1.2.使用 操作符1.3.使用 putAll 方法1.4.使用 merge 函数 前言 记录一些kotlin开发中&#xff0c;日常使用的函数和方式之类的&#xff0c;…...

Android 回答视频边播放边下载的问题

分层次的回答突出 技术深度、架构思维 和 实战优化&#xff0c;从基础实现到高阶优化&#xff1a; 一、核心技术方案&#xff08;基础回答&#xff09; 如何实现视频边下边播&#xff1f; 1. **网络请求**&#xff1a;使用 HTTP Range 请求&#xff08;Header: Range: bytes0…...

RHCSA Linux系统 数据流和重定向 tee 命令

一.数据流和重定向 1. 数据流 (1) 标准输入&#xff08;stdin&#xff0c;代码 0&#xff09;&#xff1a;默认从键盘获取输入&#xff0c;只读。 (2) 标准输出&#xff08;stdout&#xff0c;代码 1&#xff09;&#xff1a;命令执行正确信息默认输出到屏幕&#xff0c;只写…...

[ctfshow web入门] web7

信息收集 题目提示&#xff1a;版本控制很重要&#xff0c;但不要部署到生产环境更重要。 那么很有可能&#xff0c;版本控制相关的信息被部署到环境了&#xff0c;比如比如version.txt记录了一些相关配件的版本&#xff0c;git版本管理工具中的.git文件夹未删除 信息收集就是…...