一文读懂MVCC:数据库中的并发读写利器!

news/2024/5/17 12:42:05/文章来源:https://blog.csdn.net/en_joker/article/details/131020585

大家好,我是你们的小米,一个积极活泼、喜好分享技术的小伙伴。今天,我想和大家聊一聊数据库领域的一个重要话题——MVCC多版本并发控制。MVCC是MySQL和其他一些数据库系统中常用的并发控制技术,通过它,我们可以在高并发读写的场景中提高数据库的性能。让我们一起来深入了解吧!

什么是MVCC

MVCC全称为Multi-Version Concurrency Control,中文翻译为多版本并发控制。它是一种用于数据库系统中处理并发读写操作的技术。MVCC通过为每个读写操作创建多个版本的数据来解决并发冲突,从而实现了读操作与写操作之间的并发执行,提高了数据库的并发性能。

什么是当前读

在MVCC中,当前读操作是指读取最新数据版本的操作。下面是一些常见的当前读语句:

  • SELECT ... FOR UPDATE:用于读取数据并获取写锁。
  • SELECT ... LOCK IN SHARE MODE:用于读取数据并获取读锁。

什么是快照读

快照读是指读取历史数据版本的操作,也可以称为非锁定读操作。下面是一些常见的快照读语句:

  • SELECT:普通的查询语句,用于读取数据。

当前读、快照读、MVCC之间的关系

当前读和快照读是MVCC中两种不同的读操作方式。当前读获取的是最新的数据版本,可以用于读写冲突的处理,而快照读获取的是历史的数据版本,用于读取一致性的数据视图。MVCC通过管理和维护这些不同版本的数据,实现了并发读写操作

MVCC解决的问题

数据库并发场景有三种,分别是:

  • 读读冲突:多个读操作之间不会产生冲突,可以并发执行。
  • 读写冲突:读操作不会被写操作所阻塞,读操作可以读取到之前的数据版本,保证了读的一致性。
  • 写写冲突:写操作之间不会产生冲突,可以并发执行。

MVCC是一种用来解决读写冲突的无所并发控制,也就是为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照,所以MVCC可以为数据库解决以下问题:

  • 并发读写性能提升:在并发读写数据库时,MVCC可以做到在读操作时不用阻塞写操作,在写操作时不用阻塞读操作,提高了数据库并发读写的性能。
  • 事务隔离:MVCC可以解决脏读、幻读、不可重复读等事务隔离的问题,但是不能解决更新丢失问题。

MVCC实现原理

MVCC的实现原理主要依赖于记录中的三个隐藏字段、undolog、read view来实现的。

隐藏字段

MVCC通过在数据表中添加一些隐藏字段来实现多版本控制。这些隐藏字段包括:

  • DB_TRX_ID:用于标识事务的唯一ID。
  • DB_ROLL_PTR:指向undo log中的回滚段指针。
  • DB_ROW_ID:用于唯一标识一行数据。

undolog

undolog是MVCC实现中的一个重要组件,用于记录数据的修改历史。在MVCC中,insert操作和update/delete操作都会产生对应的undolog。

  • insert操作:在插入一行数据时,会生成一条insert类型的undolog,记录了插入数据的操作。
  • update和delete操作:在更新或删除一行数据时,会生成一条delete类型的undolog,记录了删除或修改之前的数据。

read view

read view是MVCC中用于管理数据版本的重要概念,它是一个逻辑数据视图。下面是一些关于read view的重要信息:

  • Read View的定义:Read view是一个事务开始时创建的数据视图,用于确定事务的隔离级别和可见性规则。
  • Read View的作用:Read view用于确定一个事务可以看到哪些数据版本,以及其他事务是否可以看到该事务修改的数据。

Read View中三个全局属性

在MVCC中,Read view具有三个全局属性,分别是trx_list、up_limit_id和low_limit_id。

  • trx_list:记录了当前活动的事务列表,其中每个事务包含一个事务ID和一个读视图。
  • up_limit_id:是一个全局的递增ID,用于判断事务的可见性。
  • low_limit_id:是一个全局的递增ID,用于判断事务的可见性。

Read View的可见性比较规则

基于上述三个全局属性,Read View的可见性比较规则如下:

  1. 如果DB_TRX_ID < up_limit_id,则当前事务能看到DB_TRX_ID 所在的记录,如果大于等于进入下一个判断;
  2. 如果 DB_TRX_ID ≥ up_limit_id,则代表 DB_TRX_ID 所在的记录在 Read View 生成后才出现的,那么对于当前事务肯定不可见,如果小于,则进入下一步判断;
  3. 判断 DB_TRX_ID 是否在活跃事务中,如果在,则代表在Read View 生成时刻,这个事务还是活跃状态,还没有 commit,修改的数据,当前事务也是看不到;如果不在,则说明这个事务在 Read View 生成之前就已经开始 commit,那么修改的结果是能够看见的。

MVCC的整体处理流程

假设有四个事务T1、T2、T3和T4,它们按顺序开始执行,并进行读写操作。MVCC的整体处理流程如下:

  1. T1开始执行时,创建一个新的read view,并设置up_limit_id和low_limit_id为无穷大。
  2. T1执行读操作,获取到数据库中的数据版本。
  3. T1执行写操作,修改数据库中的数据,并生成对应的undolog。
  4. T1提交事务,将up_limit_id设置为T1的事务ID。
  5. T2开始执行时,创建一个新的read view,并设置up_limit_id为无穷大,low_limit_id为T1的事务ID。
  6. T2执行读操作,根据read view获取到数据库中的数据版本。
  7. T3开始执行时,创建一个新的read view,并设置up_limit_id为无穷大,low_limit_id为T1的事务ID。
  8. T3执行写操作,修改数据库中的数据,并生成对应的undolog。
  9. T4开始执行时,创建一个新的read view,并设置up_limit_id为无穷大,low_limit_id为T1的事务ID。
  10. T4执行读操作,根据read view获取到数据库中的数据版本。

通过上述流程,MVCC保证了不同事务之间的并发读写操作,并根据每个事务的read view确定数据的可见性。

RC、RR级别下的InnoDB快照读区别

在InnoDB中,RC(Read Committed)和RR(Repeatable Read)是两种常见的隔离级别。在这两种隔离级别下,InnoDB的快照读有以下不同之处:

  • 在RR级别下,每个事务的read view是在事务开始时创建的,并在整个事务期间保持不变。这意味着在RR级别下,事务可以看到之前读取的数据版本,即使其他事务已经修改了数据。
  • 在RC级别下,每个语句都会创建一个新的read view,并在执行语句期间保持不变。这意味着在RC级别下,事务每次读取数据都会使用新的read view,而不会看到其他事务已经修改的数据。
  • RR级别下的快照读会导致更多的数据版本被保留在undo log中,因为每个事务的read view都需要保留。而在RC级别下,每个语句的read view只需要保留一次,因此占用的存储空间较少。
  • 总结:在RC隔离级别下,是每个快照读都会生成并获取最新的 Read View;而在RR隔离级别下,则是同一个事务中的第一个快照读会创建 Read View,之后的快照读获取的都是同一个 Read View。

总结

MVCC多版本并发控制是一种提高数据库并发性能的重要技术。通过使用当前读和快照读,MVCC能够解决读读、读写和写写冲突,并提高并发读写数据库的性能。它还能解决事务隔离的问题,但无法解决更新丢失问题。MVCC的实现原理涉及隐藏字段、undolog和read view等组件,通过管理这些组件,实现了并发读写操作。在不同的隔离级别下,快照读的行为也会有所不同。RR级别下的快照读可以看到之前读取的数据版本,而RC级别下的快照读每次读取都使用新的read view。

 

END

对于数据库开发和性能优化来说,了解和掌握MVCC技术是非常重要的。希望本篇文章能给大家带来一些启发和帮助。如果有任何问题或者想法,欢迎留言讨论!

 

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

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

相关文章

Elasticsearch文件存储

分析Elasticsearch Index文件是如何存储的&#xff1f; 主要是想看一下FST文件是以什么粒度创建的&#xff1f; 首先通过kibana找一个索引的shard&#xff0c;此处咱们就以logstash-2023.05.30索引为例 查看下shard分布情况 GET /_cat/shards/logstash-2023.05.30?vindex …

tcp shrinking window 之进退

一个有趣的问题&#xff1a;Unbounded memory usage by TCP for receive buffers, and how we fixed it 引出一个 kernel patch&#xff1a;[PATCH] Add a sysctl to allow TCP window shrinking in order to honor memory limits 但这 patch 把一个问题变成了两个问题&#…

0基础学习VR全景平台篇第32章:场景功能-嵌入文字

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 本期为大家带来蛙色VR平台&#xff0c;场景管理模块-嵌入功能文字模块&#xff01; 功能位置示意 一、本功能将用在哪里&#xff1f; 嵌入功能可对VR全景作品嵌入【图片】【视频】【文字】【标尺】四…

值得收藏 | 脑机交互作用研究

神经损伤和疾病对许多人的生活产生了巨大的影响&#xff0c;导致了许多运动障碍和日常任务无法独立完成。皮质假体系统通过脑机接口&#xff08;BCI&#xff09;接收一个动作命令来执行所需的位置&#xff0c;从而使得经历神经损伤的人能够实现部分功能恢复。BCI技术可以在侵入…

基于深度学习的目标姿态检测方法_kaic

目录 摘要 第1章 引言 1.1 研究背景和意义 1.2 国内外研究现状 1.3 主要内容 第2章 单目相机的目标姿态检测技术 2.1单目相机的工作原理 2.2目标姿态检测 2.3已有的目标姿态检测方法及其局限性 2.4本章总结 第3章 构建数据集 3.1 数据集来源 3.2数据集标注 3.3数据集分析 3.4本…

Docker安装Mysql教程(linux)

本文主要讲解如何使用Docker去安装mysql 一、搜索镜像 docker search mysql二、拉取镜像 不指定版本&#xff0c;默认为最新版&#xff0c;这里用的5.7 docker pull mysql:5.7三、创建容器&#xff08;运行镜像&#xff09; 1、内外都使用3306端口&#xff08;确保你的宿主机3…

这么好看的头像,岂不拿下!

❝ 如此好看的头像&#xff0c;怎么能不喜欢&#xff1f;&#xff1f;&#xff1f; ❞ 代码放在了最后 后续还会出一个工具&#xff0c;以便于随时打开下载。 看上述的头像是不是还是很不错的。看着网站还是✨✨每天都会有更新的✨✨。 所以&#xff0c;我动手了&#xff0c;下…

菱形图案打印、水仙花数、买汽水

目录 菱形图案打印 上三角 下三角 拓展&#xff1a;带空格直角三角形图案 代码一 代码二 水仙花数 拓展&#xff1a;变种水仙花数 买汽水 代码一 代码二 妙用汽水瓶 菱形图案打印 题目要求 其实呢这道题很多人想到直接用printf()进行输出&#xff0c;我想说的是&#…

【企业化架构部署】基于Apache搭建LAMP架构

文章目录 前言一、LMAP架构介绍1.概念2.LAMP构建顺序3.LAMP编译安装4.各组件介绍4.1 Linux4.2 Apache4.3 MySQL4.4 PHP/Perl/Python 二、服务器部署1.Apache部署2.MySQL部署3.PHP部署4.安装论坛 前言 LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整…

初识SpringBoot -- SpringBoot入门保姆级教程(一)

文章目录 前言一、初识SpringBoot1.SpringBoot简介2.用编译器IDEA创建SpringBoot项目3.在官网创建SpringBoot项目4.SpringBoot项目快速启动&#xff08;前后端分离基本能力&#xff09;5.了解SpringBoot起步依赖和启动类 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开…

【数据结构6】二叉树的基本操作

文章目录 ⭐️写在前面的话⭐️二叉树的一些基本操作1、结构定义2、先序创建这棵树3、按满二叉树方式创建4、三种递归遍历5、层次遍历6、求二叉树的深度7、求叶子结点数8、三种非递归遍历9、先序线索化二叉树10、先序线索化后遍历11、中序线索化二叉树12、中序线索化后遍历主函…

【笔记】【Javascript】javascript实现继承

前言 之前写过关于面向对象编程的文章&#xff0c;通过阅读别人的博客了解了一下Javascript实现继承的方法&#xff0c;并且使用图画的形式帮助了解&#xff0c;图是自己做的&#xff0c;若有偏差请读者帮忙指出&#xff0c;谢谢。笔记中有些个人理解后整理的笔记&#xff0c;…

【Vue】Vuex,Vue-Router

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 Vuexvue-router Vuex 将公用的数据统一存放在store(全局数据中心)中&#xff0c;实现更方便的跨…

Redis之SDS数据结构的使用

目录 序言字符串 char*字符串数组简单动态字符串SDS 序言 Redis的几种基本数据结构有字符串&#xff08;String&#xff09;、哈希&#xff08;Hash&#xff09;、列表&#xff08;List&#xff09;、集合&#xff08;Set&#xff09;、有序集合&#xff08;Sorted Set&…

企业级开发1.6 JdbcTemplate操作

JdbcTemplate操作 一、JdbcTemplate案例演示&#xff08;一&#xff09;创建数据库与表1、创建数据库2、创建用户表3、用户表添加记录4、查看用户表内容 &#xff08;二&#xff09;打开Spring项目&#xff08;三&#xff09;添加数据库相关依赖&#xff08;四&#xff09;创建…

PyCharm使用指南 - 如何创建密码短语生成器(上)

PyCharm是一种Python IDE&#xff0c;其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外&#xff0c;该IDE提供了一些高级功能&#xff0c;以用于Django框架下的专业Web开发。 PyCharm 最新下载 本文将展示如何使用免费的 PyCharm Community Edition 开…

chatgpt赋能python:Python创建venv的完全指南

Python创建venv的完全指南 在Python开发中&#xff0c;虚拟环境是一个非常有用的工具。它可以让我们在同一台计算机上拥有多个Python环境&#xff0c;而不会互相干扰。在本文中&#xff0c;我们将介绍如何使用Python创建venv&#xff08;虚拟环境&#xff09;。 什么是venv&a…

Unity制作二次元卡通渲染角色材质——1、资源分析

Unity制作二次元材质角色 回到目录 大家好&#xff0c;我是阿赵。 开始制作二次元角色材质之前&#xff0c;我觉得应该是先分析一下&#xff0c;我手上拿到的这个角色模型资源&#xff0c;总共有哪些信息是我们能用的。 所以这篇文章我不会分享具体的Shader&#xff0c;但我感觉…

pnpm对npm及yarn降维打击详解

目录 正文npm2yarnpnpm总结 正文 大家最近是不是经常听到 pnpm&#xff0c;我也一样。今天研究了一下它的机制&#xff0c;确实厉害&#xff0c;对 yarn 和 npm 可以说是降维打击。 那具体好在哪里呢&#xff1f; 我们一起来看一下。 我们按照包管理工具的发展历史&#xf…

Redis核心数据结构-01

1、String String 数据结构是简单的key-value类型&#xff0c;value其实不仅是String&#xff0c;也可以是数字。 常用命令&#xff1a;get、set、incr、decr、mget等。 应用场景&#xff1a;String是最常用的一种数据类型&#xff0c;普通的key/ value 存储都可以归为此类&…