前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >绝对不谈死概念!用人能听懂的话带你玩明白MVCC的运行机制。

绝对不谈死概念!用人能听懂的话带你玩明白MVCC的运行机制。

作者头像
程序员牛肉
发布于 2024-09-26 05:23:09
发布于 2024-09-26 05:23:09
2050
举报

大家好,我是程序员牛肉。

这篇中我不讲MVCC的死概念。那玩意网上太多了,一抓一大把。我再复制粘贴一遍没有任何意义。

如果你还不知道什么是数据库的MVCC机制,我推荐你可以看一看黑马的MySQL课程里面的MVCC机制解析,又或者是小林coding的讲解。他们对于MVCC机制是什么已经介绍的很详细了。

而我们今天对MVCC的深入理解,将通过两个问题来表达:

  • MVCC是如何防止脏读和不可重复读的?
  • MVCC机制一定能防住幻读吗?那他防不住哪些幻读?

我们来看看MVCC机制下的比较规则:

这个比较规则乍一看挺唬人的,但其实就一句话:“在MVCC机制下,一个事务要么读取自己修改过的数据,要么读取其他事务已经提交的数据。”

一定要理解我说的这句话,这将对你后面理解MVCC起到至关重要的作用。

让我们回到我开头的那个问题:MVCC是如何防止脏读和不可重复读的?

在RC的隔离级别下:

在一个事务中,每一次SELECT 都会生成一次快照,经由MVCC来确定能够读取哪个数据版本。

脏读的定义是:读取到其他事务未提交的数据。

而MVCC机制就是确保一个事务要么读取自己修改过的历史数据,要么读取其他事务已经提交的数据,这可不就防住了脏读嘛。

在RR的隔离级别下:

在一个事务中,只有第一次SELECT 会生成快照,此后一致沿用这个快照。

不可重复度的定义是:连续两次读取数据的结果不一致。

而MVCC是根据快照来判断当前事务能够读取哪一条数据历史记录的。如果我们一直沿用一个快照,那么可读取的数据版本就是同一个。同一个数据版本读数据得到的结果当然是一样的。这可不就防住了不可重复读嘛。

介绍完这两个,其实我们还可以做一下引申:为什么RC隔离级别下防不住不可重复读?

相信聪明的你很快就能知道答案:RC隔离级别下,每一次SELECT 都会生成一个新的快照。那么读取到的数据版本就可能不一致。自然有可能会出现幻读了。

第二个问题:MVCC机制一定能防住幻读吗?那他防不住哪些幻读?

看到我的问题,你就应该知道MVCC防不住所有的幻读。那MVCC能够防住哪些可能会发生幻读的场景呢?

下列的场景,当我们的事务B尝试往查寻结果集中尝试插入数据的时候,也不会发生幻读。

原因很简单:在事务B中虽然对结果集进行了插入,但我们的事务A在事务B还没有提交之前就进行了第二次查询。

也就是说:事务A是看不见这条事务B未提交数据的。而也符合MVCC的运行机制:在MVCC机制下,一个事务要么读取自己修改过的数据,要么读取其他事务已经提交的数据。

这其实就是B站很多UP主说的:“MVCC能解决当前读下的幻读”。但说实话按照我这种理解方式要好理解很多。

那MVCC防不住哪些幻读场景呢?

我们轻松一推理就知道了:在MVCC机制下,一个事务要么读取自己修改过的数据,要么读取其他事务已经提交的数据。

那我们有没有办法让这条插入记录变成事务A的历史修改数据呢?

当然有了,只要在事务B插入这条数据之后,我们update一下这条数据,就会把这条数据变成事务A的历史修改数据。

那么基于MVCC机制,事务A就可以读取到这条数据。

在这种情况下,MVCC是防不住幻读的,因为事务A的update把事务B的insert语句变成了自己的历史修改数据。

而MVCC让一个事务要么读取自己修改过的数据,要么读取其他事务已经提交的数据。

而这也就是很多UP主的“MVCC防不住一个事务中既有当前读,又有快照读的情况。”

在这里还需要注意了,很多人可能会认为事务A中的upate读不到事务B的插入数据,因为事务B的那条数据还未提交。

如果你有这个想法,那你还需要好好了解一下MySQL中的“快照读”和“当前读”。insert和update都是当前读,直接对最新的表数据进行修改,是没有快照这一说的。

那我们要如何防住这种幻读情况呢?

其实很简单,手动加锁就行了。加一个next_key 锁,锁住待查寻的数据范围就好了。而这也是MySQL的解决方案:

本图片来自小林coding

介绍到这里,相信你已经了解了“MVCC的运行机制”。我在介绍的时候已经尽量尝试少用专业名词和概念了。希望我的文章可以帮助到你。

对于MVCC,你的理解是什么呢?欢迎在评论区留言

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员牛肉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
0[生信技能树]生信服务器配置全攻略
1查看cpu信息 yinli@pc-System-Product-Name:~$ cat /proc/cpuinfo |grep pro processor : 0 processor : 1 processor : 2 processor : 3 processor : 4 processor : 5 processor : 6 processor : 7 processor : 8 proces
Y大宽
2019/05/29
1.3K0
docker - 占满根目录空间的解决方案
Docker 默认会占用根目录的空间,时间久了就会吧根目录占满,本文记录解决方案。 问题复现 不知不觉根目录已经没有空间,ls 的补全都会报错。 cannot create temp file for here-document: No space left on devic 可以看到 /已经没有空间了 $ df -h Filesystem Size Used Avail Use% Mounted on udev
为为为什么
2022/08/05
1.6K0
Linux基础篇——Linux磁盘操作(磁盘基础知识、分类、分区、挂载、卸载、扩容)详解「建议收藏」
  假如你有个大木桶要装东西,如果木桶没有划分层,所有东西全部放入里面,虽然可以装,但是对大木桶的使用就合不合理,造成杂乱无章,寻找东西时候也耗时,甚至还有不同物品之间不能存放在一起而导致危险,那更好的做法自然是给大木桶画一下不同的区域,分成不同的层,每个层放不同的东西,即安全,寻找起来也方便;
全栈程序员站长
2022/09/01
8.2K0
Linux基础篇——Linux磁盘操作(磁盘基础知识、分类、分区、挂载、卸载、扩容)详解「建议收藏」
搞它!!!Linux系统LVM原理及磁盘配额(PV、VG、LV、PE的关系,手把手教你,嘴对嘴的传达)
当你在使用linux系统时,为了满足当时的工作需要你装了一个100G的磁盘,但是你发现随着公司的发展,和需要储存数据的空间的增大,你会不会重新买些磁盘给装到机器上去呢?每装一次重新分配一次磁盘,就复制一次数据,那这样对于工作的你,是不是非常的麻烦?如果我们用LVM就能解决这类的磁盘管理问题。
不吃小白菜
2020/09/03
6.5K0
搞它!!!Linux系统LVM原理及磁盘配额(PV、VG、LV、PE的关系,手把手教你,嘴对嘴的传达)
MongoDB使用iscsi
Linux平台:尝试部署MogoDB,并使用iscsi作为其data目录 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下,添加更多的节点,可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。 # 连接iscsi root in awCqlxb in
summerking
2022/09/16
2.6K0
MongoDB使用iscsi
sudo rm-rf引发的惨案——Linux硬盘的分区和挂载
前不久,刚使用组里的一台服务器,这台服务器平时用的人不多, 没有严格的管理机制,大家都使用同一个用户名进行远程连接,人人都有sudo权限。我因为对Linux不是非常熟悉,使用管理员权限下执行了一个删除文件的操作(sudo rm-rf),直接把系统搞崩,差点给全组造成难以估量的损失,从删库到跑路差点在我身上上演。。
zstar
2022/10/31
3K0
sudo rm-rf引发的惨案——Linux硬盘的分区和挂载
Linux下对lvm逻辑卷分区大小的调整(针对xfs和ext4不同文件系统)
当我们在安装系统的时候,由于没有合理分配分区空间,在后续维护过程中,发现有些分区空间不够使用,而有的分区空间却有很多剩余空间。如果这些分区在装系统的时候使用了lvm(前提是这些分区要是lvm逻辑卷分区),那么就可以轻松进行扩容或缩容!不同文件系统类型所对应的创建、检查、调整命令不同,下面就针对xfs和ext2/3/4文件系统的lvm分区空间的扩容和缩容的操作做一记录: ----------------------------------------------------------------------
洗尽了浮华
2018/01/22
4.1K0
Linux命令补充
使用wget -O下载并以不同的文件名保存(-O:下载文件到对应目录,并且修改文件名称)
GH
2020/03/19
9660
0基础带你入门Linux之简介
而Linux则很简单,只有一个根目录,也可以说只有一个盘,整个系统所有的东西都是在根目录下的
凯子坚持C
2024/09/23
1070
0基础带你入门Linux之简介
磁盘管理 之 parted命令添加swap,文件系统
本文介绍了Linux系统中,如何与Windows互相传输文件。包括使用lrzsz工具进行上传和下载,以及使用tar进行打包压缩。同时,还介绍了如何长传文件,以及下载文件。
惨绿少年
2017/12/27
1.8K0
十大最有用的Linux命令
在这篇文章中,我列出了一些针对Linux新手的最基本但最有用的Linux命令。 您可以键入以下命令来管理服务器。 对于初学者来说,这些命令是最简单的学习VPS或Linux服务器管理的方法。
用户8710806
2021/06/08
3860
Linux (RHEL 5.4)下安装 Oracle 10g R2
如转载,请注明出处:http://blog.csdn.net/robinson_0612/archive/2010/03/30/5431428.aspx      虽然 Oracle 10g Database Release 2 已经推出几年了,但这个版本仍然为很多初学者学习的版本,下面详细讲述了安装 Oracle 10g 的步骤。 一、 linux 的版本选用     目前 linux(RHEL) 使用的主要版本为 5.4 版,可以到下面的地址下载其安装文件。        RHEL5.4 下载   http://download.chinaunix.net/download/0013000/12623.shtml 二、关于 linux 的安装     很多初学者使用的是 XP 系统上的虚拟机来安装 Linux ,因此本文也是在虚拟机上安装 Linux 然后再安装 Oracle 10g. 至于虚拟机可以使用 VMware 6.5 Workstation 版,这个可以到百度 ,Google 找一下,比较多。安装了 linux 时,我们需要特殊的配置一下 Oracle 的安装环境,关于这个配置 Oracle 安装环境,请参考: VmWare6.5.2下安装 RHEL 5.4(配置 Oracle安装环境) 三、安装 Oracle 前的环境检查     1. 下载 Oracle 10g R2        Oracle 10g for Linux   http://www.oracle.com/technology/software/products/database/index.html     2. 查看 Linux 内核参数,有点多余,作为初学者,还是可以练习一下。请确保高于 2.6.9 -5.0.5.EL 以上内核              强烈建议大家安装 SecureCRT 或 VNC 工具,这样不必来回在 XP 和 Linux 下切换。        uname –r [root@localhost ~]# uname -r        2.6.18 -164.el5xen     3. 查看 CPU 、内存、 Swap 及磁盘可用空间        内存:至少 1GB ,下图中我的内存仅 900MB        Swap :一般为可用物理内存的 2 倍,比如设定为 2GB        /Temp 分区:至少 400MB        Oracle 安装目录所在的分区:至少 4GB [root@localhost ~]# free -m                     total       used       free     shared    buffers     cached        Mem:           900        568        331          0         56        356        -/+ buffers/cache:        154        745        Swap:         2251          0       2251 [root@localhost ~]# df -h        Filesystem            Size  Used Avail Use% Mounted on        /dev/sda2             6.4G  3.8G  2.3G  63% /        /dev/sdd1             6.8G  144M  6.3G   3% /u01        /dev/sdc2             1.2G   34M  1.1G   3% /home        /dev/sdc1             760M   17M  704M   3% /tmp        /dev/sda1             456M   18M  415M   5% /boot        tmpfs                    450M     0  450M   0% /dev/shm        none                     450M   104K  450M   1% /var/lib/xenstored        /dev/hdc               2.8G  2.8G     0 100% /media/RHEL_5.4 i386 DVD 四、配置安装环境     1. 安装补丁包        关于确认补丁包的是否已安装,可以使用下述方式来查看        rpm -q gcc make
Leshami
2018/08/07
1.2K0
[Linux]常用命令、组合命令以及输入输出重定向
删除非空目录,还有一种更为简单的方法:把-R(或recursive)和-f(或--force)选项结合起来使用。-r选项告诉rm命令进入到它发现的每个子目录中去删除文件,而-f选项只是告诉rm命令完成任务但不要因为些细节问题(比如文件夹非空)而烦扰用户。
祥知道
2020/03/10
1.7K0
DELL存储SCv2000/2020基础配置与使用
描述: 最近业务需要需要将原本装有VMware vSphere的机器直接安装Ubuntu 20.04 TLS,并通过SAS线缆从DELL Storage SCv 2020链接我们的UBUNTU 物理主机上进行SCSI磁盘的挂载共享使用,以下是一些简单的说明;
全栈工程师修炼指南
2020/10/26
8.1K0
DELL存储SCv2000/2020基础配置与使用
ubuntu18的宽带连接问题
我的ubuntu18现在 Adsl连接出现问题,在网络哪里找不到宽带连接,做一个问题解决方案。 这是参考文献: ubuntu下pppoe拨号 ubuntu的ADSL拨号上网主要是无线网情况下 ADSL(PPPOE)接入指南 ubuntu 16.04 上不了网?DSL消失?更新网卡驱动? Ubuntu16.04怎么设置宽带连接 ubuntu16.04拨号上网及无线驱动安装 Ubuntu更换网卡驱动 升级Ubuntu 16.04 LTS后 DSL拨号上网(ppp)连接自动断开解决办法 ubun
热心的社会主义接班人
2018/04/27
3.4K0
ubuntu18的宽带连接问题
使用rclone挂载onedrive扩容服务器空间
在 rclone 官网https://rclone.org/downloads/下载适用于 Windows 的最新版客户端,解压到磁盘当中,将文件夹重命名为rc(方便以下操作。。)。按住键盘上win+R输入powershell打开命令行,执行以下命令。
用户1316967
2022/01/18
9.8K0
使用aspera加速从中国的GSA数据库下载测序文件
值得注意的是人类的数据跟其它物种在的GSA(国家基因组科学数据中心)数据库的存储有不一样的规则:
生信技能树
2024/11/25
3470
使用aspera加速从中国的GSA数据库下载测序文件
Linux下IP SAN共享存储操作记录
一、简单介绍 SAN,即存储区域网络(storage area network and SAN protocols),它是一种高速网络实现计算机与存储系统之间的数据传输。常见的分类是FC-SAN和IP-SAN两种。FC-SAN通过光纤通道协议转发scsi协议;IP-SAN通过TCP协议转发scsi协议,也就是IP 地址。存储设备是指一台或多台用以存储计算机数据的磁盘设备,通常指磁盘阵列,主要厂商EMC、日立等。 iSCSI(internet SCSI)技术由IBM公司研究开发,是一个供硬件设备使用的、可以在
洗尽了浮华
2018/03/28
6.6K0
Linux下IP SAN共享存储操作记录
linux基础命令介绍十二:磁盘与文件系统
本篇讲述磁盘管理相关的命令。计算机中需要持久化存储的数据一般是保存在硬盘等辅助存储器中。硬盘一般容量较大,为了便于管理和使用,可以将硬盘分成一到多个逻辑磁盘,称为分区;为使分区中的文件组织成操作系统能够处理的形式,需要对分区进行格式化(创建文件系统);在linux中,对于格式化后的分区,还必须经过挂载(可简单理解为将分区关联至linux目录树中某个已知目录)之后才能使用。
用户5030870
2019/04/11
4.9K0
linux基础命令介绍十二:磁盘与文件系统
Linux之/dev目录介绍
Linux中的dev文件目录的全称是device设备的英文,这个目录包含了所有linux中使用的外部设备,但是不包含外部设备的驱动信息。我们先来看看这个目录中包含哪些文件吧:
AsiaYe
2019/11/06
8.4K0
推荐阅读
相关推荐
0[生信技能树]生信服务器配置全攻略
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档