Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
数据库技术知识点总结之一——事务
标准的隔离级别中,Oracle 只有 Read committed, Serializable 两种,此外还有 ReadOnly, WriteOnly 两种级别。其中 ReadOnly 是 Serializable 的子集。
剑影啸清寒
2020/07/13
5160
美团三面:一直追问我, MySQL 幻读被彻底解决了吗?
之前有位小伙伴美团三面,一直被追求「幻读是否被 MySQL 可重复度隔离级别彻底解决了?」
小林coding
2022/10/27
5330
美团三面:一直追问我, MySQL 幻读被彻底解决了吗?
MySQL八:读懂MVCC多版本并发控制
mysql在并发的情况下,会引起脏读,幻读,不可重复读等一系列的问题,为解决这些问题,引入了mvcc的机制。本文就详细看看mvcc是怎么解决脏读,幻读等问题的。
云扬四海
2022/09/26
7390
深入了解Mysql的MVCC机制
早上上班途中,趁着坐地铁的功夫翻了翻高性能mysql这本书,准备回顾一下MVCC这块的知识点,因为书中对MVCC的讲解不是很多,于是我很快便看完了这一段落,但是文章末尾有一段话引起了我的思考。
敲得码黛
2021/11/01
1.4K0
深入了解Mysql的MVCC机制
mysql事务隔离级别与MVCC
事务A和事务B都读取了同一行数据, 比如原数据行的值是100,事务A是将数值读取出来+1并更新, 事务B是读取数值+2并更新。当事务A和事务B都读取到了100,事务A首先完成并更新为101,事务B随后完成更新成了102。这样事务B就把事务A的结果覆盖了。
leobhao
2022/06/28
3980
mysql事务隔离级别与MVCC
从 MySQL 的事务 到 锁机制 再到 MVCC
转眼又一年~~2023马上就要到尾声了,在最后的几天中,我想给大家分享一下 MySQL 的一些小知识。
绿毛龟
2024/01/19
1740
从 MySQL 的事务 到 锁机制 再到 MVCC
白话数据库中的MVCC
说MVCC(Multiversion concurrency control,多版本并发控制)之前,先从数据库的ACID说起。ACID其中一个就是I。也就是Isolation,隔离性。
ImportSource
2018/10/23
1.6K0
白话数据库中的MVCC
MySQL - 并发事务问题及解决方案
中我们初步了解了 MVCC 的原理及其实现。 随着数据库并发事务处理能力的增强,数据库资源的利用率也会大大提高,从而提高了数据库系统的事务吞吐量,可以支持更多的用户并发访问。
小小工匠
2021/08/17
1.1K0
MySQL的可重复读级别能解决幻读吗
之前在深入了解数据库理论的时候,了解到事物的不同隔离级别可能存在的问题。为了更好的理解所以在MySQL数据库中测试复现这些问题。关于脏读和不可重复读在相应的隔离级别下都很容易的复现了。但是对于幻读,我发现在可重复读的隔离级别下没有出现,当时想到难道是MySQL对幻读做了什么处理?
星哥玩云
2022/08/17
7320
MySQL的可重复读级别能解决幻读吗
结合图文一起搞懂MySQL事务、MVCC、ReadView!
上次讲完MySQL的三大日志 undolog、redolog、binlog后,有必要把关于MySQL事务分析的文章马上给续上,我们知道在多并发事务处理的MVCC【多版本并发控制】中是有涉及到undo log日志的。
小许code
2023/09/18
4K4
结合图文一起搞懂MySQL事务、MVCC、ReadView!
MVCC 原理
一个事务读取了另外一个事务修改后记录 强调的是 update 和delete ,只需要锁住满足条件的记录即可
王小明_HIT
2020/06/16
7431
MVCC 原理
MVCC 原理分析、MySQL是如何解决幻读的
还记得MySQL事务四大特性、并发事务问题、事务隔离级别吗?幻读又是什么呢?如果忘记可以到这里重新温习:MySQL基础:SQL分类DDL、DML、DQL、DCL;函数、约束、多表查询、事务、并发事务四大问题、事务隔离级别——脏写、脏读、不可重复读、幻读
寻求出路的程序媛
2024/05/22
7310
MVCC 原理分析、MySQL是如何解决幻读的
MVCC实现原理之ReadView(一步到位)
使用 READ UNCOMMITTED 隔离级别的事务,由于可以读到未提交事务修改过的记录,所以直接读取记录 的最新版本就好了。
一个风轻云淡
2022/11/15
1.3K0
MVCC实现原理之ReadView(一步到位)
详解MySQL隔离级别
在不同隔离级别下,事务A会有哪些不同的返回结果,也就是图中的V1、V2、V3的返回值分别是什么。
用户10384376
2023/02/26
9260
详解MySQL隔离级别
美团三面: MySQL 幻读被彻底解决了吗?
作者:小林coding 八股文网站:xiaolincoding.com 之前有位小伙伴美团三面,一直被追问「幻读是否被 MySQL 可重复度隔离级别彻底解决了?」 之前我也提到过,MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象(并不是完全解决了),解决的方案有两种: 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据
博文视点Broadview
2022/10/10
2.9K0
美团三面: MySQL 幻读被彻底解决了吗?
InnoDB的MVCC机制
事务可以通过start transaction语句开始一个事务,然后要么使用commit提交事务将所修改的数据持久保存,要么使用rollback撤销所有修改
平凡的学生族
2019/10/08
4510
InnoDB的MVCC机制
MVCC 水略深,但是弄懂了真的好爽!
前面写了一篇文章和大家分享了 MySQL 中查询表记录数的问题,里边涉及到一个知识点 MVCC 多版本并发控制。这个问题不搞懂,总感觉缺点什么。因此今天我想花点时间和大家聊一聊 MVCC。
江南一点雨
2022/01/24
3560
MVCC 水略深,但是弄懂了真的好爽!
深入理解InnoDB的MVCC多版本并发机制
上面我们说到了InnoDB在RR隔离级别下解决了幻读问题,又保证了高并发的读取(避免了读写串行化),那他到底是如何做的呢?
绿水长流z
2025/01/03
1210
深入理解InnoDB的MVCC多版本并发机制
Mysql 专栏 - MVCC机制
mvcc机制是mysql解决事务问题一项重要机制,通过这个机制,mysql解决了关于事务的问题:脏写、脏读、重复读的问题,但是默认的不可重复读的情况下还是会出现幻读的问题。
阿东
2021/10/08
6640
事务隔离级别中的可重复读能防幻读吗?
前言 每次谈到数据库的事务隔离级别,大家一定会看到这张表. 其中,可重复读这个隔离级别,有效地防止了脏读和不可重复读,但仍然可能发生幻读,可能发生幻读就表示可重复读这个隔离级别防不住幻读吗? 我不管从
码农阿宇
2019/09/17
3.2K1
事务隔离级别中的可重复读能防幻读吗?
相关推荐
数据库技术知识点总结之一——事务
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档