数据库的MVCC机制详解

news2025/4/18 15:12:49

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状态(已提交或未提交)和事务活跃状态,删除过期版本

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2332002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

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的简介 …

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;直接…

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

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

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组件提供了一种强大的机制…

Spark Core编程

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

无人机装调与测试

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

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

图书列表 实现服务器代码(计算图书总数量查询当前页需要展示的书籍) 后端响应时&#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…

[ctfshow web入门] web7

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

DeepSeek-V3 API:开启下一代AI应用开发的新篇章

引言 在人工智能技术日新月异的今天&#xff0c;大型语言模型(LLM)正以前所未有的速度改变着我们与技术互动的方式。DeepSeek-V3作为国内领先的大语言模型之一&#xff0c;其API的开放为开发者提供了强大的AI能力集成方案。 DeepSeek-V3 API的核心优势 1.强大的语言理解与生…

go语言应该如何学习

以下是学习Go语言的高效路径及关键技巧&#xff0c;结合多个优质来源整理而成&#xff0c;适合不同基础的学习者&#xff1a; 一、基础语法快速入门&#xff08;1-2周&#xff09; 1、环境搭建 下载安装Go SDK&#xff0c;配置GOPATH和GOROOT环境变量&#xff0c;推荐使用Go…

NO.84十六届蓝桥杯备战|动态规划-路径类DP|矩阵的最小路径和|迷雾森林|过河卒|方格取数(C++)

路径类dp是线性dp的⼀种&#xff0c;它是在⼀个nm的矩阵中设置⼀个⾏⾛规则&#xff0c;研究从起点⾛到终点的⽅案数、最⼩路径和或者最⼤路径和等等的问题 矩阵的最小路径和_牛客题霸_牛客网 状态表⽰&#xff1a; dp[i][j]表⽰&#xff1a;到达[i, j]位置处&#xff0c;最⼩…

React + TipTap 富文本编辑器 实现消息列表展示,类似Slack,Deepseek等对话框功能

经过几天折腾再折腾&#xff0c;弄出来了&#xff0c;弄出来了&#xff01;&#xff01;&#xff01; 消息展示 在位编辑功能。 两个tiptap实例1个用来展示 消息列表&#xff0c;一个用来在位编辑消息。 tiptap灵活富文本编辑器&#xff0c;拓展性太好了!!! !!! 关键点&#x…