多版本并发控制:MVCC的作用和基本原理

多版本并发控制:MVCC的作用和基本原理

  • 1、MVCC简介
    • 1.1 快照读与当前读的区别
      • 1.1.1 快照读
      • 1.1.2 当前读
    • 1.2 数据库的读写问题
    • 1.3 MVCC的作用
  • 2、MVCC实现原理之ReadView
    • 2.1 什么是ReadView
    • 2.2 ReadView的设计思路
    • 2.3 MVCC整体操作流程

1、MVCC简介

1.1 快照读与当前读的区别

mysql在读数据的场景下,根据是否加锁分为了2种读的方式:

1.1.1 快照读

不加锁的简单的select都属于快照读,即不加锁的非阻塞读。比如:

SELECT * FROM students WHERE ...

之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于MVCC。他在很多情况下,避免了加锁操作,降低了开销。

1.1.2 当前读

当前读读取的是记录最新的数据。加锁的SELECT,或者对数据进行增删改查都会进行当前读。比如:

SELECT * FROM student LOCK IN SHARE MODE;  # 共享锁
SELECT * FROM student FOR UPDATE;  # 排他锁
INSERT INTO student VALUES ...;  # 排他锁
DELETE FROM student WHERE ...;  # 排他锁
UPDATE student SET ...;  # 排他锁

1.2 数据库的读写问题

数据库多事务场景下的读-读不会存在并发问题,写-写场景存在并发问题,因此一定需要加锁。

读-写、或者写-读场景下如何处理?

方案一:读操作也采用加锁的方式。
比如,在银行存款的事务中,需要先读取账户余额,然后再进行存/取操作,最后写入数据库中。在这个过程中,是不希望其他事务在该事务还未结束的情况下访问该余额。这种情况下,在读取余额的时候就需要进行加锁操作了。这样就可以保证本次操作结束后的金额,一定是和预期一致的。

1.3 MVCC的作用

数据库的读写问题,除了采用加锁的方式解决,还可以通过MVCC的方式解决。

MVCC(Multiversion Concurrency Control)多版本并发控制,通过数据行的多个版本管理实现数据库的并发控制。即查询一些正在被另一个事务更新的数据行时,可以看到他们被更新之前的值,不用等待另一个事务释放锁。

所谓的MVCC,就是生成一个ReadView,通过ReadView找到符合条件的记录版本(历史版本由undo日志构建)。查询语句只能读到在生成ReadView之前已提交事务做的修改,不影响其他事务进行写操作,因此可以解决读写问题。相比于加锁的方式解决读写问题,可以大幅提高并发性能。

2、MVCC实现原理之ReadView

MVCC的实现依赖于:隐藏字段、Undo Log、Read View

undo日志版本链中索引记录都包含2个必要的隐藏列:

  • trx_id:每次一个事务对某条索引记录进行修改时,都会把该事务的事务id赋值给trx_id隐藏列。
  • roll_pointer:每次对某条索引记录进行修改时,都会把旧版本写入到undo日志中,这个隐藏列相当于一个指针,可以通过它来找到该记录修改前的信息。

以下图举例,其中蓝色部分为页面的当前记录,绿色部分为undo日志。
在这里插入图片描述

2.1 什么是ReadView

多个事务对同一行记录进行更新会产品多个历史快照,这些历史快照保存在undo log里。如果一个事务想要查询这个行记录,怎么判断读取哪个版本的记录呢?这个时候就可以用上Readview了,它解决了多事务场景下的可见性的问题。

Readview就是事务在使用MVCC机制进行快照读操作时产生的读视图。当事务启动时,会生成数据库系统当前的一个快照,Innodb为每个事务构造了一个数组,用来记录并维护系统当前未提交事务的ID。

2.2 ReadView的设计思路

Readview要解决的核心问题是:判断版本链中的哪个版本是当前事务可见的。

为此,Readview设计了4个核心字段:

  1. creator_trx_id:创建Readview的事务ID。只有对表做增删改操作时才会分配事务ID,读操作的事务ID默认值为0。
  2. trx_ids:表示生成Readview时,当前系统中未提交事务的事务id列表。
  3. up_limit_id:当前未提交事务列表中最小的事务id。
  4. low_limit_id:生成Readview时,系统应该分配给下一个事务的id值。

举例:现在有id未1,2,3这3个事务,然后id为3的事务提交了。此时一个新的读事务在生成Readview时,trx_ids的值是:[1,2],up_limit_id的值是1,low_limit_id的值是4。

有了Readview,在访问某条记录时,根据以下步骤判断记录的某个版本是否可见

  1. 如果被访问版本的trx_id值与Readview中的creator_trx_id值相同:表明当前呢事务在访问自己修改的记录,所以该版本可以被当前事务访问。
  2. 如果被访问版本的trx_id值小于Readview中的up_limit_id值:表明生成该版本的事务在当前事务生成Readview之前就已经提交了,所以该版本可以被当前事务访问。
  3. 如果被访问版本的trx_id值大于等于Readview中的low_limit_id值:表明生成该版本的事务在当前事务生成Readview之后才开启,所以该版本不可以被当前事务访问。
  4. 如果被访问版本的trx_id值在Readview中的up_limit_id值和low_limit_id值之间,需要判断一下trx_id值是否在trx_ids列表中。
    1)如果在:说明创建Readview时,生成该版本的事务还未提交,该版本不可以被访问。
    2)如果不在:说明创建Readview时,生成该版本的事务已被提交,该版本可以被访问。

2.3 MVCC整体操作流程

查询记录时,MVCC操作流程如下。如果某个版本的数据对当前事务不可见的话,就顺着版本链找下一个版本的数据,继续按照流程进行判断。

  1. 获取事务自己的版本号,即事务ID
  2. 生成Readview
  3. 查询数据,根据数据的版本号(trx_id)值按照2.2中的规则进行判断
  4. 如果不符合2.2中Readview规则,从undo log中获取历史快照
  5. 循环执行,最后返回符合2.2中Readview规则中的数据。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker—搭建Harbor和阿里云私有仓库

Harbor概述 Harbor是一个开源的企业级Docker Registry管理项目,由VMware公司开发。‌它的主要用途是帮助用户迅速搭建一个企业级的Docker Registry服务,提供比Docker官方公共镜像仓库更为丰富和安全的功能,特别适合企业环境使用。‌12 Harb…

HarmonyOS:创建应用静态快捷方式

一、前言 静态快捷方式是一种在系统中创建的可以快速访问应用程序或特定功能的链接。它通常可以在长按应用图标,以图标和相应的文字出现在应用图标的上方,用户可以迅速启动对应应用程序的组件。使用快捷方式,可以提高效率,节省了查…

从表人的相关单词聊起

英文单词是繁多的,甚至海量的,这和老外的思维方式有关,他们通常会为同一类事物的具体的东西或子类事物也专门创建一个单词来进行表达、表示或应对,这增加了表达的直接性和精确性,但是,也轻而易举地就创建出…

低代码系统-产品架构案例介绍、轻流(九)

轻流低代码产品定位为零代码产品,试图通过搭建来降低企业成本,提升业务上线效率。 依旧是从下至上,从左至右的顺序 名词概述运维层底层系统运维层,例如上线、部署等基础服务体系内置的系统能力,发消息、组织和权限是必…

2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文

模型设计思路与创新点: 建模的时候应该先确定我们需要建立什么类的模型?优化类还是统计类?这个题需要大量的数据分析,因此我们可以建立一个统计学模型。 统计学建模思路:观察规律,建立模型,参…

自由学习记录(32)

文件里找到切换颜色空间 fgui中的 颜色空间是一种总体使用前的设定 颜色空间,和半透明混合产生的效果有差异,这种问题一般可以产生联系 动效就是在fgui里可以编辑好,然后在unity中也准备了对应的调用手段,可以详细的使用每一个具…

【2025AI发展预测】2.2025的风口与发展,我们如何主动拥抱这一浪潮

个人主页:Icomi 大家好我是一颗米,本系列文章包含我个人的一些思考见解,以及在网上看到的相关资讯,结合本人的认识,在那基础上进行加工输出,希望能帮助到各位,若您对本系列感兴趣,欢…

操作系统(Linux Kernel 0.11Linux Kernel 0.12)解读整理——内核初始化(main init)之硬盘初始化

前言 对硬盘和软盘块设备上数据的读写操作是通过中断处理程序进行的。内核每次读写的数据量以一个逻辑块(1024 字节)为单位,而块设备控制器则是以扇区(512字节)为单位访问块设备。在处理过程中,内核使用了读写请求项等待队列来顺序地缓冲一次读写多个逻…

利用机器学习创建基于位置的推荐程序

推荐系统被广泛应用于不同的应用程序中,用于预测用户对产品或服务的偏好或评价。在过去的几分钟或几小时里,你很可能在网上遇到过或与某种类型的推荐系统进行过互动。这些推荐系统有不同的类型,其中最突出的包括基于内容的过滤和协作过滤。在…

【AI论文】Video-MMMU:评估从多学科专业视频中获取知识的能力

摘要:人类通过三个认知阶段获取知识:感知信息、理解知识以及运用知识解决新问题。视频作为这一学习过程的有效媒介,促进了这些认知阶段的逐步推进。然而,现有的视频基准测试未能系统地评估大型多模态模型(LMMs&#xf…

【C++高并发服务器WebServer】-9:多线程开发

本文目录 一、线程概述1.1 线程和进程的区别1.2 线程之间共享和非共享资源1.3 NPTL 二、线程操作2.1 pthread_create2.2 pthread_exit2.3 pthread_join2.4 pthread_detach2.5 patch_cancel2.6 pthread_attr 三、实战demo四、线程同步五、死锁六、读写锁七、生产消费者模型 一、…

C语言学习强化

前言 数据的逻辑结构包括: 常见数据结构: 线性结构:数组、链表、队列、栈 树形结构:树、堆 图形结构:图 一、链表 链表是物理位置不连续,逻辑位置连续 链表的特点: 1.链表没有固定的长度…

【C++探索之路】STL---string

走进C的世界,也意味着我们对编程世界的认知达到另一个维度,如果你学习过C语言,那你绝对会有不一般的收获,感受到C所带来的码云风暴~ ---------------------------------------begin--------------------------------------- 什么是…

【WebRTC - STUN/TURN服务 - COTURN配置】

在WebRTC中,对于通信的两端不在同一个局域网的情况下,通信两端往往无法P2P直接连接,需要一个TURN中继服务,而中继服务可以选用 COTURN 构建。 注:COTURN 是一个开源的 TURN(Traversal Using Relays around…

React 前端框架实战教程

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 引言 React 是由 Facebook 开发的前端 JavaScript 库,旨在构建高效、灵活的用户界面,尤其适用于单页应用…

MiniMax-01中Lightning Attention的由来(线性注意力进化史)

目录 引言原始注意力线性注意力因果模型存在的问题累加求和操作的限制Lightning AttentionLightning Attention-1Lightning Attention-2 备注 引言 MiniMax-01: Scaling Foundation Models with Lightning Attention表明自己是第一个将线性注意力应用到如此大规模的模型&#…

互联网医院成品|互联网医院软件源码

互联网医院系统带来的好处是显而易见的,其通过先进的互联网技术为医疗行业带来了巨大的变革。以下将从多个方面详细阐述其带来的益处。 一、便捷的医疗服务 互联网医院系统为患者提供了更为便捷的医疗服务。患者无需再亲自前往医院,只需通过电脑、手机等…

unity学习20:time相关基础 Time.time 和 Time.deltaTime

目录 1 unity里的几种基本时间 1.1 time 相关测试脚本 1.2 游戏开始到现在所用的时间 Time.time 1.3 时间缩放值 Time.timeScale 1.4 固定时间间隔 Time.fixedDeltaTime 1.5 两次响应时间之间的间隔:Time.deltaTime 1.6 对应测试代码 1.7 需要关注的2个基本…

Centos7系统php8编译安装ImageMagick/Imagick扩展教程整理

Centos7系统php8编译安装ImageMagick/Imagick扩展教程整理 安装php8安装ImageMagick1、下载ImageMagick2、解压并安装3、查看是否安装成功 安装imagick扩展包 安装php8 点我安装php8 安装ImageMagick 1、下载ImageMagick wget https://www.imagemagick.org/download/ImageMa…

RabbitMQ模块新增消息转换器

文章目录 1.目录结构2.代码1.pom.xml 排除logging2.RabbitMQConfig.java3.RabbitMQAutoConfiguration.java 1.目录结构 2.代码 1.pom.xml 排除logging <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/PO…