一文读懂 Mysql MVCC

news2024/11/19 17:19:10

💕💕 推荐:体系化学习Java(Java面试专题)

文章目录

  • 1、什么是 MVCC
  • 2、什么是当前读、快照读
  • 3、MVCC 具体解决什么问题
  • 4、MVCC 的实现原理
    • 4.1、4个隐式字段
    • 4.2、undo 日志
    • 4.3、Read View
  • 5、使用 MVCC 时,需要注意什么问题

在这里插入图片描述

1、什么是 MVCC

MVCC(Multi-Version Concurrency Control)是一种多版本并发控制技术,常用于数据库管理系统中,用于支持事务的并发执行。MVCC 技术可以在读取数据时不产生锁,同时保证数据的一致性。具体来说,MVCC 技术会在每个数据行上保存多个版本的数据,每个版本都有一个时间戳,当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取,从而避免了读取数据时的锁定操作。同时,MVCC 技术还可以通过回滚日志和垃圾回收机制来保证数据的一致性和完整性。MVCC 技术在 InnoDB 存储引擎中得到了广泛的应用,成为了 InnoDB 存储引擎的一个重要特性。

正是因为有了 MVCC,所以 Mysql 的并发性能才会更好。

2、什么是当前读、快照读

当前读和快照读是 InnoDB 存储引擎中的两种读取数据的方式。

当前读:是指在读取数据时,使用的是最新的数据版本。当前读可以通过 SELECT … FOR UPDATE (排它锁)或者 SELECT … LOCK IN SHARE MODE (共享锁)等语句实现。在当前读的情况下,如果其他事务正在修改该数据行,当前读会被阻塞,直到其他事务释放锁。

快照读:是指在读取数据时,使用的是指定时间点的数据版本。快照读可以通过 SELECT … FROM … AS OF 或者 SELECT … FROM … VERSIONS BETWEEN … AND … 等语句实现。在快照读的情况下,如果其他事务正在修改该数据行,快照读不会被阻塞,而是读取该数据行的历史版本。快照读可以提高并发读取数据的效率,但是可能会读取到已经被修改的数据行。

SELECT ... FROM ... AS OF 是一种快照读取数据的方式。它可以在读取数据时指定一个时间点,然后读取该时间点的数据版本,而不是当前的数据版本。这种方式不会对其他事务产生锁定,因此可以提高并发性能。在使用 AS OF 语句时,InnoDB 存储引擎会从回滚日志中读取指定时间点的数据版本,并返回给用户。需要注意的是,使用 AS OF 语句时,需要保证指定的时间点在当前事务开始之前,否则可能会读取到未提交的数据,导致数据不一致。

SELECT ... FROM ... VERSIONS BETWEEN ... AND ... 是一种快照读取数据的方式,可以读取指定时间范围内的数据版本。在使用该语句时,需要指定开始时间和结束时间,然后 InnoDB 存储引擎会读取这个时间范围内的所有数据版本,并将它们返回给用户。这种方式不会对其他事务产生锁定,因此可以提高并发性能。需要注意的是,使用 VERSIONS BETWEEN 语句时,需要保证指定的时间范围在当前事务开始之前,否则可能会读取到未提交的数据,导致数据不一致。

当前读适合于需要修改数据的场景,而快照读适合于只需要读取数据的场景。

3、MVCC 具体解决什么问题

首先说下数据库的并发场景可以分为以下几种:

  1. 读写并发:多个事务同时对同一数据进行读和写操作。这种场景需要使用并发控制机制来保证数据的一致性和完整性。

  2. 写写并发:多个事务同时对同一数据进行写操作。这种场景需要使用锁定机制来保证数据的一致性和完整性。

  3. 读读并发:多个事务同时对同一数据进行读操作。这种场景不需要使用并发控制机制,可以提高数据库系统的并发性能。

  4. 隔离级别并发:不同事务之间的隔离级别不同,可能会导致数据不一致的问题。这种场景需要使用事务隔离级别机制来保证数据的一致性和完整性。

  5. 死锁并发:多个事务之间相互依赖,可能会出现死锁的情况。这种场景需要使用死锁检测和解决机制来避免死锁的发生。

而 MVCC 主要解决数据库系统中的并发控制问题。在多用户并发访问数据库时,如果不进行并发控制,可能会导致数据不一致的问题。传统的并发控制方式是使用锁定机制,即在读取或修改数据时,需要先对数据行进行加锁,防止其他事务同时对该数据行进行修改。这种方式虽然可以保证数据的一致性,但是会降低并发性能,因为同时只有一个事务可以对数据行进行操作。
MVCC 技术通过在每个数据行上保存多个版本的数据,每个版本都有一个时间戳,来实现并发控制。当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取,从而避免了读取数据时的锁定操作。同时,MVCC 技术还可以通过回滚日志和垃圾回收机制来保证数据的一致性和完整性。MVCC 技术可以提高数据库系统的并发性能,同时保证数据的一致性。

MVCC + 悲观锁:MVCC 解决读写冲突,悲观锁解决写写冲突
MVCC + 乐观锁:MVCC解决读写冲突,乐观锁解决写写冲突

4、MVCC 的实现原理

在这里插入图片描述
MVCC 的实现原理主要是在每个数据行上保存多个版本的数据,并通过版本号和时间戳来实现并发控制。具体实现步骤如下:

  1. 在每个数据行上保存多个版本的数据。每个版本都有一个唯一的版本号和时间戳,用于标识该版本的数据是在何时被修改的。

  2. 当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取。如果该事务的时间戳早于某个数据版本的时间戳,则该数据版本对该事务不可见,因为该数据版本是在该事务开始之后被修改的。

  3. 当一个事务需要修改数据时,会先将原始数据行复制一份,并在新复制的数据行上进行修改。同时,该事务会生成一个新的版本号和时间戳,并将新版本的数据行插入到数据库中。这样,原始数据行和新数据行就形成了一个版本链。

  4. 当一个事务提交时,会将该事务所修改的数据行的最新版本号和时间戳更新到事务提交记录中。这样,其他事务就可以根据该事务的提交记录来选择合适的数据版本进行读取。

  5. 当一个事务回滚时,会将该事务所修改的数据行的最新版本号和时间戳恢复到事务开始时的状态。这样,其他事务就可以根据该事务的回滚记录来选择合适的数据版本进行读取。

  6. 为了避免版本链过长,数据库系统会定期进行垃圾回收,删除不再需要的版本。这样可以减少数据库系统的存储空间和提高查询性能。

为了解决读写冲突主要是依赖记录中的 4个隐式字段,undo日志 ,Read View 来实现的

4.1、4个隐式字段

MVCC(多版本并发控制)是一种用于数据库系统的并发控制技术,它通过在每个数据行上保存多个版本的数据,每个版本都有一个时间戳,来实现并发控制。在 MVCC 中,每个数据行都有四个隐式字段,分别是:

  1. Transaction ID:事务 ID,表示修改该数据行的事务的 ID。
  2. Rollback Pointer:回滚指针,指向该事务的回滚日志,用于撤销该事务对该数据行的修改。
  3. Row Start:行开始时间戳,表示该数据行的版本开始时间。
  4. Row End:行结束时间戳,表示该数据行的版本结束时间。

在这里插入图片描述

这四个隐式字段是 MVCC 技术实现并发控制的关键,它们记录了每个数据行的修改历史和版本信息,用于支持并发事务的读写操作。当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取,从而避免了读取数据时的锁定操作。同时,MVCC 技术还可以通过回滚日志和垃圾回收机制来保证数据的一致性和完整性。

4.2、undo 日志

Undo 日志是数据库系统中的一种重要的日志记录机制,用于支持事务的回滚和 MVCC(多版本并发控制)技术的实现。当一个事务执行修改操作时,数据库系统会将修改前的数据记录到 Undo 日志中,以便在事务回滚时可以恢复到修改前的状态。同时,在 MVCC 技术中,Undo 日志还用于保存每个数据行的历史版本信息,以便支持并发事务的读写操作。

下面是一个使用 Undo 日志的 SQL 示例:
假设有一个表 t,其中包含两个字段 id 和 name,现在执行以下 SQL:

UPDATE t SET name = 'new_name' WHERE id = 1;

执行该 SQL 语句时,数据库系统会将 id 为 1 的数据行修改前的值记录到 Undo 日志中。如果事务回滚,则可以使用 Undo 日志将该数据行恢复到修改前的状态。

另外,如果该表使用了 MVCC 技术,在每个数据行中也会保存 Undo 日志,用于支持并发事务的读写操作。当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取。如果需要回滚该事务,则可以使用 Undo 日志将该数据行恢复到指定的历史版本。

4.3、Read View

Read View 是 MySQL 中用于实现 MVCC 的一种机制,用于支持并发事务的读操作。在 MySQL 中,每个事务都有自己的 Read View,用于确定该事务可以读取到哪些数据版本。Read View 由以下两个部分组成:

  1. Trx ID 列表:该列表记录了当前事务启动时,已经提交的事务 ID 列表。
  2. 快照版本号:该版本号记录了当前事务启动时,数据库系统的快照版本号。

在执行读操作时,MySQL 会将当前事务的 Read View 与数据行的版本信息进行比较,从而确定当前事务可以读取哪些数据版本。如果数据版本早于当前事务的快照版本号或者是由未提交的事务所产生的版本,则当前事务无法读取该数据版本。

以下是一个示例 SQL 语句,说明 Read View 的工作原理:

-- 事务 A
START TRANSACTION;
SELECT * FROM t WHERE id = 1;

 -- 事务 B
START TRANSACTION;
UPDATE t SET name = 'new_name' WHERE id = 1;
COMMIT;

 -- 事务 A
SELECT * FROM t WHERE id = 1;
COMMIT;

在上述示例中,事务 A 在启动时会创建自己的 Read View,并记录当前数据库系统的快照版本号。在第一个 SELECT 语句中,事务 A 会根据自己的 Read View 读取 id 为 1 的数据行,此时由于事务 B 已经对该数据行进行了修改,因此事务 A 无法读取到该数据行的旧版本。

在事务 B 中,执行 UPDATE 语句时,会创建一个新的数据行版本,并将该版本的事务 ID 记录到 redo 日志中。同时,由于该版本的事务 ID 还未提交,因此该版本不会被事务 A 的 Read View 所包含。

在事务 A 中的第二个 SELECT 语句中,由于该语句在事务 A 启动之后执行,因此会使用事务 A 的当前 Read View 进行读取。由于事务 A 的 Read View 不包含事务 B 所提交的事务 ID,因此事务 A 可以读取到 id 为 1 的数据行的旧版本。

5、使用 MVCC 时,需要注意什么问题

  1. 事务启动时间:事务的启动时间会影响到事务能够读取到哪些数据版本。如果事务启动时间早于某个数据版本的创建时间,则该事务可以读取到该数据版本。因此,需要确保事务启动时间在需要读取的数据版本之后。

  2. 版本回收:MVCC 技术需要维护多个数据版本,因此需要定期清理不再需要的版本,避免占用过多的存储空间。在 MySQL 中,使用 purge 线程来定期清理不再需要的版本。

  3. 长事务:长时间运行的事务会占用大量的 MVCC 版本,导致存储空间不足或性能下降。因此,需要避免长时间运行的事务,或者使用合适的事务隔离级别来减少 MVCC 版本的数量。

  4. 并发度:MVCC 技术可以提高数据库系统的并发性能,但是也需要考虑并发度的问题。如果并发度过高,可能会导致 MVCC 版本的数量过多,从而影响性能。

  5. 事务隔离级别:在使用 MVCC 技术时,需要根据具体的业务需求选择合适的事务隔离级别。不同的隔离级别会影响 MVCC 版本的数量和读取的数据版本,从而影响并发性能和数据一致性。需要根据具体的业务需求进行选择。

在这里插入图片描述

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊

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

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

相关文章

CSS灯光效果,背景黑金效果

先看效果 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>灯光效果</title><link href"https://fonts.googleapis.com/css2?familyCinzel:wght700&amp;dis…

MyBatis 动态sql移除最后的逗号 mybatis trim标签用法 Mybatis 去掉最后的逗号符号

MyBatis 动态sql移除最后的逗号 mybatis trim标签用法 Mybatis 去掉最后的逗号符号 一、概述 在使用MyBatis 写动态sql时&#xff0c;经常会遇到要移除最后多余的 符号 &#xff0c;and &#xff0c; or之类的关键字 &#xff1b; 还有可能需要移除的前缀 where &#xff0c; s…

续-初识JAVaScript---(2)

初识JavaScript ———&#xff08;2&#xff09;&#xff01;&#xff01;&#xff01; 一、关于JavaScript中的数据类型 虽然在JS中的变量在声明的时候不需要指定数据类型&#xff0c;但是在赋值的时候&#xff0c;每一个数据还是有类型的&#xff0c;所以还是需要学习JS中…

c语言第一课---------它来了,它来了,带着薪资走来了

作者前言: 这是我的gitee仓库:https://gitee.com/qin-laoda/python-exercises 有兴趣的小可爱们可以点进去看看,里面有我写的代码我们一起来借鉴 由于本人的自我介绍已经自我介绍过了,在我的的第一篇博客里,有兴趣的小可爱可以去看看, 作者的建议 下面我们简单介绍学好C语言…

【Python】Python进阶系列教程-- Python3 JSON 数据解析(九)

文章目录 前言Python 编码为 JSON 类型转换对应表&#xff1a;JSON 解码为 Python 类型转换对应表&#xff1a;json.dumps 与 json.loads 实例 前言 往期回顾&#xff1a; Python进阶系列教程-- Python3 正则表达式&#xff08;一&#xff09;Python进阶系列教程-- Python3 C…

LLVM 标准 C++ 排序算法

Nature 官网发表《深度强化学习发现更快的排序算法》。 排序或散列这样的基本算法在任何一天都会被使用数万亿次1。随着计算需求的增长&#xff0c;这些算法的性能变得越来越重要 算法已经集成到 LLVM 标准 C排序库中&#xff0c;使用强化学习的新算法替换掉了原有的 LLVM libc…

STM32CubeMX | 44 - 使用GPIO点亮单总线RGBLED

一、单总线RGBLED 1. 硬件连接 在DragonFly上有四个全彩灯相连: 其中RGB_LED连接到STM32的PB9引脚。 2. 单总线通信协议 单总线通信协议中,表示bit0和bit1的码型如下: 时序值如下: 驱动一个单总线RGBLED只需要传输24bit颜色数据即可(MSB,高位优先),格式如下(注意…

OpenGL 冯氏光照模型

1.简介 现实世界的光照是极其复杂的&#xff0c;而且会受到诸多因素的影响&#xff0c;这是我们有限的计算能力所无法模拟的&#xff0c;冯氏光照模型的主要结构由3个分量组成&#xff1a;环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看…

V4L2框架解析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、概览二、流程简介三、关键结构体四、模块初始化五、处理用户空间请求 一、概览 相机驱动层位于HAL Moudle与硬件层之间&#xff0c;借助linux内核驱…

MacOS使用docker安装nginx

文章目录 一、docker安装nginx1、查看可用的nginx2、安装Nginx镜像3、查看是否安装成功4、安装成功后执行nginx5、查看容器6、本地验证 二、创建本地挂载文件1、第一步&#xff1a;宿主机创建目录2、第二步&#xff1a;将docker安装的nginx里面文件复制到宿主机3、第三步&#…

安洵杯2023wp - ukfc战队

喜提牛马第23名&#xff0c;不过对于我来说尽力了。 主方向逆向、密码学都极限输出了、但是第二道同模的题差一个点没想通&#xff0c;没得写很难受。 补题&#xff1a;NULL Web CarelessPy 目录 Web CarelessPy Confronting robot Reverse ez_cpp babythread 3D_m…

深入学习 Mysql 引擎 InnoDB、MyISAM

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 &#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#…

【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)

一、线性表1.1 概念与特点1.2 线性表的存储结构1.3 常见操作1.4 应用场景 二、链表2.1 链表简介2.2 单向链表&#xff08;单链表&#xff09;2.21 基本概念2.22 单链表基本操作2.23 C语言实现▶ 带头结点▶ 不带头结点 2.3 双向链表2.31 基本概念2.32 与单链表比较2.33 双向链表…

【Python】Python进阶系列教程-- urllib(十三)

文章目录 前言urllib.requesturllib.errorurllib.parseurllib.robotparser 前言 往期回顾&#xff1a; Python进阶系列教程-- Python3 正则表达式&#xff08;一&#xff09;Python进阶系列教程-- Python3 CGI编程&#xff08;二&#xff09;Python进阶系列教程-- Python3 My…

C++面向对象丨3. 函数提高——默认参数、占位参数和函数重载

文章目录 系列文章目录基础入门面向对象 1 函数默认参数2 函数占位参数3 函数重载 系列文章目录 基础入门 C基础入门丨1. 初识C像极了C语言C基础入门丨2. 数据类型基础C基础入门丨3. 搞明白4类运算符——运算符C基础入门丨4. 程序结构有哪几种&#xff1f;——程序流程结构C基…

LVS负载均衡群集--NAT模式

目录 前言 一&#xff1a;企业群集应用概述 1、集群的含义 2、问题 3、 解决方法 二、企业群集分类 1、根据群集所针对的目标差异&#xff0c;可分为三种类型 2、负载均衡群集(Load Balance Cluster) 3、 高可用群集(High Availability Cluster) 4、 高性能运算群集(Hi…

华为OD机试真题 JavaScript 实现【素数伴侣】【2023 B卷 100分】,附详细解题思路

一、题目描述 若两个正整数的和为素数&#xff0c;则这两个正整数称之为“素数伴侣”&#xff0c;如2和5、6和13&#xff0c;它们能应用于通信加密。现在密码学会请你设计一个程序&#xff0c;从已有的 N &#xff08; N 为偶数&#xff09;个正整数中挑选出若干对组成“素数伴…

3 个令人惊艳的 AI 项目,开源了!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 过去一周&#xff0c;从外界看&#xff0c;AI 貌似放缓了进步速度&#xff0c;但只有身处其中的人才能知道&#xff0c;AI 一直没有停下进化的脚步。 以下是 GitHub 过去一周&#xff0c;诞…

一杯奶茶,成为AIGC+CV视觉的前沿弄潮儿!

击上方“机器学习与AI生成创作”&#xff0c;关注星标 获取有趣、好玩的前沿干货&#xff01; 【AI生成创作与计算机视觉】知识星球 2022、2023年开始&#xff0c;基于扩散模型的AI绘画、ChatGPT系列大模型主导的AIGC狂潮已来&#xff01;大模型下的科研、工业应用方向&#xf…

YOLOV3——你总能在这找到你想要的答案

目录 一&#xff1a;前言&#xff1a; 二&#xff1a;更快&#xff0c;更强 网络结构图 其他基础操作&#xff1a; Darknet53的由来 三&#xff1a;最明显的特点&#xff1a; 四&#xff1a;多scale 五&#xff1a; 为什么vgg越深效果反而越差了&#xff1f; 六&#…