当前位置: 首页 > news >正文

数据库 MVCC 详解

目录

1. 什么是 MVCC?

2. MVCC 的好处?

3. 快照读?当前读分别是什么?怎么理解?

3.1 快照读

3.2 当前读

4. 数据库的四种隔离级别

5.  MVCC 实现原理

5.1 隐藏字段

5.2 undo log(版本链)

5.3 readView

6. readView 深层详解

7. MVCC中是如何解决不可重复读的?

8. 间隙锁解决幻读问题(补充点)


1. 什么是 MVCC?

MVCC 英文全称叫 "Multiversion Concurrency Control",翻译过来就是 "多版本并发控制"。在 MySQL 众多存储引擎中只有 InnoDB 中实现了 MVCC 机制。

2. MVCC 的好处?

首先我们要清楚,在 InnoDB 存储引擎下,假设事务A我们对一行数据进行修改操作,是会对这一行数据进行加写锁的;如果此时事务B来查询这一行数据,它就要加读锁,读锁与写锁冲突,所以十五B、加锁不成功,它就必须等待事务A操作执行完毕释放写锁之后才能去进行读操作。

而有了 MVCC 的加入,我们的事务B再去查询该行数据时,就不需要等待事务A释放锁可以直接查询,查询方式是快照读(下面会解释到),查询到的是事务A修改数据之前当前行的数据,提高了数据库的并发效率。

总之一句话:MVCC 是通过数据行的多版本管理来实现数据库的并发控制,提高数据库的并发性能。

3. 快照读?当前读分别是什么?怎么理解?

3.1 快照读

我们姑且把刚才的事务A的查询操作理解为写操作,事务B的查询操作理解为读操作;在 MVCC 下,这里的读指的是快照读。了解在 Linux 操作系统和 Git 代码管理的大致应该清楚,我们可以通过 Linux 操作系统的快照将系统回溯到之前的某个版本,Git 也可以通过回溯版本返回至之前的某个代码版本。MVCC 中的快照与这两者大致意思相近,可以类比理解。

数据在修改之前和修改之后版本是不一样的,我们读取别人正在操作的数据时,可以读取该数据操作之前的快照,就可以避免读写锁互斥导致阻塞等待这一现象。

3.2 当前读

当前读就很好理解了,没有 MVCC 时,数据库是靠加锁来避免数据安全性问题,加的锁都是悲观锁。共享锁,排它锁都属于是当前读的一种范畴。

我们去读取数据,读取到的一定是当前数据,没有数据版本这一说法。假设要去读一个正在被修改的数据,是会阻塞的,只有别人修改完,才能去执行当前读这一操作,也可以理解为同步读。

4. 数据库的四种隔离级别

数据库有四种隔离级别。它们的隔离级别由低到高,并发能力由高到低。

没有 MVCC 的情况下

读未提交:解决了脏写问题;

读已提交:解决了脏写,脏读问题;

可重复读:解决了脏写,脏读,不可重复读;

串行化:    解决了脏写,脏读,不可重复读,幻读所有问题;

在有 MVCC 的情况下

可重复读:解决了脏写,脏读,不可重复读,幻读所有并发问题。数据库默认采用的也是可重复读,解决幻读正是因为采用了 MVCC 。

读已提交和可重复读的读数据方式采用的都是快照读的方式。读未提交则不可以,因为读未提交独到的就是最新的数据,无法使用快照;串行化也不可以,因为加锁的缘故,也无法使用快照。

5.  MVCC 实现原理

MVCC 实现原理主要依赖于三部分,隐藏字段,undo log版本链,readView。

5.1 隐藏字段

对于 InnoDB 存储引擎的表来说,它的聚簇索引记录(理解为每行数据即可)中都会有两个必要的隐藏字段 trx_id(事务id) 和 roll_pointer(回滚指针)。没有主键的表会有第三个额外的隐藏主键字段。隐藏字段的主要作用就是对每次数据操作进行标记区分并记录操作之前的数据的地址。

我就以下面这幅图来给各位解析一下 trx_id 和 roll_pointer.

trx_id:每次一个事务对聚簇索引的记录做改动,都会把该事务的事务id赋值给隐藏字段。

roll_pointer:每次对聚簇索引的记录做改动时,都会把旧的版本写入到 undo 日志中去,然后这个隐藏列相当于一个指针,可以通过它来找到该记录修改之前的数据。

如上图,假设与四个事务A,B,C,D。事务A插入数据,事务B,C,D均对插入的数据做了修改。四个事务在对数据进行增删改查的时候,数据库就会给这四个事务的隐藏字段 trx_id 以自增的方式赋值,这里 假设分别赋值为 1,2,3,4。

roll_pointer 回滚指针则是指向当前数据修改之前的数据值,倘若事务回滚,就会返回到之前的数据。

5.2 undo log(版本链)

如上所示四个事务进行的四次数据更新操作,每次数据操作之后,数据库都会把操作之前的旧值存放到 undo 日志中记录下来,随着更新次数的增多,每次记录都会由隐藏字段中的 roll_pointer 指针连接起来形成链表,所形成的链表我们就称之为版本链,链表的头节点就是当前数据最新的节点。

5.3 readView

刚才我们说到了版本链,既然一条数据经历了多次操作,有那么多个版本,我们在查询数据并进行操作的时候,是怎么知道该选择哪个版本的数据的呢?一定是查询操作最新的吗?这是不一定的。查询操作哪个版本的数据取决于我们的第三个重要元素 readView。

readView 就是事务在使用 MVCC 机制对数据库中的数据操作时产生的读视图。当事务开启之后,会生成数据库当前系统的一个快照,InnoDB 会为每个事务构建一个数组,用来记录并维护当前系统活跃事务的id (这里的活跃指代的是事务正在操作数据但是没有进行提交)。

6. readView 深层详解

readView 是MVCC 三个中最重要的组成部分,也是面试 MVCC 时经常问道的一个点。

readView 的核心原理主要体现在 READ COMMITTD(读已提交)和 REPEATABLE READ(可重复读) 两种隔离级别上。

READ COMMITTD:在每次进行 SELECT 查询操作的时候都会去生成一个 readView;

REPEATABLE READ:每开启一个事物才会生成一个 readView,一个事务的所有SQL语句共享一个 readView。

readView 有多个属性,m_ids 就可以理解为生成的数组记录,如下图所示,基于以下几种属性, 一共有四种可能情况。

情况一  trx_id == creator_trx_id:说明这条记录就是当前事务插入所形成的,自己插入的数据自己肯定可以访问;

情况二 trx_id < min_trx_id:    min_trx_id表示的是正在活跃的事务最小的 id,而所有活跃的事物都是未提交的,所以就可以查询得到,不会出现读未提交的情况;

情况三 trx_id > max_trx_id:   max_trx_id表示要分配给下一个事务的 id,二我们要查询的数据的 id 却比待分配的事物的 id 还要大,这是不可能查得到的。

情况四 min_trx_id <= trx_id <= max_trx_id:如果 trx_id 是在m_ids 中,则不可以访问这个版本,因为在此区间内则说明此当前事务正在进行中还没提交,不能访问其他事务未提交的数据,否则可能会产生脏读。如果不在m_ids  中,说明当前事务已经是 commit 提交过了的,则可以访问。

7. MVCC中是如何解决不可重复读的?

在 MVCC 中 可重复读的隔离级别下,它也解决了幻读。在 MVCC 下,它是给每一个事务生成一个 readView,整个事务的执行过程中用的都是同一个 readView。

举个最简单的例子,如下所示

(1)假设现在事务A与事务B并发操作来查询 student 表,事务A 执行查询操作,执行查询操作之前会生成一个 readView,我们姑且称之为 readView_1 ,事务A从始至终使用的都是 readView_1;

(2)此时事务B来修改 student 数据,又生成了一个 readView ,我们称之为 readView_2,然后事务B率先修改完毕并提交;

(3)事务A在事务B提交之后才进行的查询,按道理来说因为事务B修改了数据,我们会产生不可重复读,但是因为事务A从始至终都是用的 readView_1 ,所以 事务A在进行查询操作的时候,查询到的其实还是事务B修改之前的数据,由此就解决了不可重复读。

8. 间隙锁解决幻读问题(补充点)

刚才我已经解释过了 MVCC 中是如何解决不可重复读问题的,在 InnoDB 存储引擎中,幻读的问题也得到了解决,解决的方式是利用间隙锁;

还以下面这幅图举例说明

假设事务A与事务B并发执行,事务A要查询 id > 1的用户数据,那么在查询之前,数据库会对 id = 1 之后的区间加上间隙锁,也就是说在事务A执行期间,其他线程不可以在 id > 1 之后插入数据;当有其他操作想要插入数据时,会阻塞等待,只有事务A执行完毕释放了间隙锁,其他线程或者说事务才能进行插入操作,由此就避免了幻读的产生。

相关文章:

数据库 MVCC 详解

目录 1. 什么是 MVCC&#xff1f; 2. MVCC 的好处&#xff1f; 3. 快照读&#xff1f;当前读分别是什么&#xff1f;怎么理解&#xff1f; 3.1 快照读 3.2 当前读 4. 数据库的四种隔离级别 5. MVCC 实现原理 5.1 隐藏字段 5.2 undo log(版本链) 5.3 readView 6. re…...

process.nextTick和vue的nextTick区别

事情的起因是代码里用了nextTick&#xff0c;然后提交代码的时候才发现&#xff0c;引入的是process的&#xff0c;然后改成了使用vue的nextTick发现效果不生效了&#xff0c;然后百度查了查两者的区别&#xff1a; process.nextTick是nodejs自带的&#xff0c;而在浏览器中执…...

小程序实现一个 倒计时组件

小程序实现一个 倒计时组件 需求背景 要做一个倒计时&#xff0c;可能是天级别&#xff0c;也可能是日级别&#xff0c;时级别&#xff0c;而且每个有效订单都要用&#xff0c;就做成组件了 效果图 需求分析 需要一个未来的时间戳&#xff0c;或者在服务度直接下发一个未来…...

【四万字】网络编程接口 Socket API 解读大全

Socket 是网络协议栈暴露给编程人员的 API&#xff0c;相比复杂的计算机网络协议&#xff0c;API 对关键操作和配置数据进行了抽象&#xff0c;简化了程序编程。 本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍&#xff0c;从而更好的理解 socket 编程。…...

无涯教程-JavaScript - ISREF函数

描述 如果指定的值是参考,则ISREF函数返回逻辑值TRUE。否则返回FALSE。 语法 ISREF (value) 争论 Argument描述Required/OptionalvalueA reference to a cell.Required Notes 您可以在执行任何操作之前使用此功能测试单元格的内容。 适用性 Excel 2007,Excel 2010,Exce…...

Android:获取MAC < 安卓系统11 <= 获取UUID

1.核心代码 主要的UseMac.java import android.annotation.SuppressLint; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import an…...

线程的几种状态

目标&#xff1a; 1. 线程的几种状态的含义 2. 状态之间的切换条件 目录 新建&#xff08;new&#xff09;线程 可运行&#xff08;Runnable&#xff09;状态 运行&#xff08;Running&#xff09;状态 阻塞&#xff08;Blocked&#xff09;状态 等待&#xff08;Waiting…...

kubernetes集群yaml文件与kubectl工具

k8s集群中对资源管理和资源对象编排部署都可以通过声明样式(yaml)文件来解决&#xff0c;也就是可以把需要对资源对象操作编辑到yaml格式文件中&#xff0c;我们把文件叫做资源清单文件&#xff0c;通过kubectl命令直接使用资源清单文件就可以实现对大量的资源对象进行编排部署…...

python基础语法(三)

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412;个人主页 &#x1f978;&#x1f978;&#x1f978;C语言 &#x1f43f;️&#x1f43f;️&#x1f43f;️C语言例题 &#x1f423;&#x1f413;&#x1f3c0;python 运…...

Haproxy集群与常见的Web集群调度器

文章目录 1. Web集群调度器概述1.1 Web集群调度器简介1.2 调度器类别1.2.1 常用软件类1.2.2 常用硬件类 2. Haproxy软件介绍2.1 Haproxy简介2.2 支持功能2.3 主要特性2.4 常用调度算法2.4.1 轮询&#xff1a;RR&#xff08;Round Robin&#xff09;2.4.2 最小连接数&#xff1a…...

centos免密登录

centos免密登录 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.知道服务器密码的情况 ssh-keygen -t rsa #上面的命令后三次回车#然后把想要免密登录的服务器加进来 ssh-copy-id -i /root/.ssh/id_rsa.pub root192.168.10.115 #免密码登录被控的主机&#xff08;ip是…...

学Python的漫画漫步进阶 -- 第十四步

学Python的漫画漫步进阶 -- 第十四步 十四、网络通信14.1 基本的网络知识14.1.1 TCP/IP14.1.2 IP地址14.1.3 端口14.1.4 HTTP/HTTPS 14.2 搭建自己的Web服务器14.3 urllib.request模块14.3.1 发送GET请求14.3.2 发送POST请求 14.4 JSON数据14.4.1 JSON文档的结构14.4.2 JSON数据…...

OpenCV(四十二):Harris角点检测

1.Harris角点介绍 什么是角点&#xff1f; 角点指的是两条边的交点&#xff0c;图中红色圈起来的点就是角点。 Harris角点检测原理&#xff1a;首先定义一个矩形区域&#xff0c;然后将这个矩形区域放置在我的图像中&#xff0c;求取这个区域内所有的像素值之和&#xff0c;之…...

C++数据结构题:DS 顺序表--连续操作

建立顺序表的类&#xff0c;属性包括&#xff1a;数组、实际长度、最大长度&#xff08;设定为 1000 &#xff09; 该类具有以下成员函数&#xff1a; 构造函数&#xff1a;实现顺序表的初始化。 插入多个数据的 multiinsert(int i, int n, int item[]) 函数&#xff0c;实…...

DM@命题公式@主范式的性质和应用@数理逻辑解决数字电路全加器问题

文章目录 abstract主合取范式与主析取范式间的关系&#x1f47a;主范式存在及唯一性定理例 主范式的性质&#x1f47a;求公式的成真与成假赋值主析取范式直接得到主合取范式 判断公式的类型 n n n元命题公式的主析取范式(主合取范式)的个数判断两个命题公式是否等值 给出一个满…...

基于微信小程序+Springboot线上租房平台设计和实现【三端实现小程序+WEB响应式用户前端+后端管理】

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

Xilinx FPGA 7系列 GTX/GTH Transceivers (2)--IBERT

IBERT GTX IBERT核心提供了基础广泛的物理介质附件(PMA)评估7系列FPGA GTX收发器的演示平台。可参数化以使用不同GTX收发器和时钟拓扑,IBERT核心也可以定制使用不同的线速率、参考时钟速率和逻辑宽度。数据模式生成器和每个所需的GTX收发器都包含了检查程序,给出了几个不同…...

Python 文件介绍和正则表达式

文章目录 Python 文件和正则表达式文件打开文件读取文件直接读取 read()&#xff1a;逐行读取采用 **for** 循环&#xff1a;采用 readlines()&#xff1a; 正则表达式匹配规则re 模块match 方法&#xff1a;search 方法group 方法split 方法编译&#xff1a;compile 方法 Pyth…...

ueditor百度富文本编辑器粘贴后html丢失class和style样式

问题 项目经理从123在线编辑上排版好的文章&#xff0c;粘贴到项目的编辑器上&#xff0c;样式完全乱了, 排版是这样的&#xff1a; 复制到ueditor后的格式&#xff1a; 这天差地别呀&#xff0c;于是打开代码模式&#xff0c;发现section的属性全没了 但是&#xff0c;sp…...

人脸自动贴国旗

&#xff08;一&#xff09;简介 国庆快到了&#xff0c;每年这个时候&#xff0c;大家的头像都会贴上国旗水印&#xff0c;然后我就像这刚好可以用opencv dilb实现一个简单的自动将国旗贴在人脸上&#xff0c;刚好配合gradio写一个简单的demo gradio官方文档 &#xff08;…...

异步FIFO设计

1 FIFO简介 FIFO的本质是RAM&#xff0c;具有先进先出的特性。 FIFO的基本使用原则&#xff1a;空时不能读&#xff0c;满时不能写 FIFO的两个重要参数&#xff1a;宽度和深度 FIFO的两种类型&#xff1a; 同步FIFO&#xff1a;读写时钟相同&#xff0c;通常用来做数据缓存…...

学习python和anaconda的经验

PYTHON 1 常用命令 1.1 1.1 注释 Python注释多行的方法有以下三种:使用ctrl+/实现多行注释、在每一行的开头使用shift+#键、输入’‘’ ‘’或者"“” “”",将要注释的代码插在中间 1.2 def init( ):函数 区分两个函数: 1.def init(self): 这种形式在__init_…...

【Linux】多线程【上】

文章目录 前言1、Linux线程概念1-1、什么是线程&#xff1f;1-1-1、如何看待页表1-1-2、回顾进程地址空间1-1-3、页表怎么进行虚拟地址到物理地址的映射的&#xff1f;1-1-4、Linux中线程的概念&#xff08;重点&#xff09;1-1-5、原生线程库1-1-6、代码测试1-1-7、知识点&…...

生成式人工智能在高等教育 IT 中的作用

作者&#xff1a;Jared Pane 通过将你大学的数据与公共 LLMs 和 Elasticsearch 安全集成来找到你需要的答案。 根据 2023 年 4 月 EDUCAUSE 的一项调查&#xff0c;83% 的受访者表示&#xff0c;生成式人工智能将在未来三到五年内深刻改变高等教育。 学术界很快就询问和想象生…...

黑龙江省DCMM认证、CSMM认证、CMMM认证、知识产权等政策奖励

2023年8月28日 为深入落实党的二十大精神&#xff0c;认真落实省第十三次党代会关于创新龙江建设的部署要求&#xff0c;全面贯彻新发展理念&#xff0c;融入和服务构建新发展格局&#xff0c;实施创新驱动发展战略&#xff0c;着力建设创新龙江&#xff0c;不断塑造振兴发展新…...

腾讯云2023年云服务器优惠活动价格表

腾讯云经常推出各种云产品优惠活动&#xff0c;为了帮助大家更好地了解腾讯云服务器的价格和优惠政策&#xff0c;下面给大家分享腾讯云最新云服务器优惠活动价格表&#xff0c;助力大家轻松上云&#xff01; 一、轻量应用服务器优惠活动价格表 1、轻量应用服务器&#xff1a;…...

Sleuth--链路追踪

1 链路追踪介绍 在大型系统的微服务化构建中&#xff0c;一个系统被拆分成了许多模块。这些模块负责不同的功能&#xff0c;组合成系统&#xff0c;最终可以提供丰富的功能。在这种架构中&#xff0c;一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上&…...

MyBatis初级

文章目录 一、mybatis1、概念2、JDBC缺点2.1、之前jdbc操作2.2 、原始jdbc操作的分析 3、mybatis的使用3.1、导入maven依赖3.2、新建表3.3、实体类3.4、编写mybatis的配置文件3.5、编写接口 和 映射文件3.6、编写测试类3.7、注意事项 4、代理方式开发5、mybatis和spring整合5.1…...

Spring 学习(二)AOP

一、什么是AOP Aspect Oriented Programming&#xff0c;即面向切面编程。对一个大型项目的代码而言&#xff0c;整个系统要求关注安全检查、日志、事务等功能&#xff0c;这些功能实际上“横跨”多个业务方法。在一般的OOP编程里&#xff0c;需要在每一个业务方法内添加相关非…...

笔记1.1 计算机网络基本概念

计算机网络是通信技术与计算机技术紧密结合的产物 通信系统模型&#xff1a; 计算机网络是一种通信网络 计算机网络是互连的、自洽的计算机集合。 互连&#xff1a;互联互通 自洽&#xff1a;无主从关系 通过交换网络互连主机 Internet&#xff1a;数以百万计的互连的计算设…...

wordpress 添加产品/南昌网站优化公司

2007年上班的第一天,只有一句话: 2007, New Year, New Life and New Future! 转载于:https://www.cnblogs.com/zygoses2gether/archive/2007/01/04/611149.html...

企业网站建设一条龙服务内容/百度人工服务热线24小时

需求中规定---只能出现不多于十个的运算符 1.那么进行随机数&#xff0c;对整个算式的长度进行规定与限制 随机&#xff1a; 单纯的rand()会返回一个0至RAND_MAX之间的随机数值&#xff0c;而RAND_MAX的值与int位数有关&#xff0c;最小是32767。不过rand()是一次性的&#xff…...

烟台网站建设外贸/java培训班学费一般多少

在该示例中&#xff0c;可选地使用LSA(使用SVD)来执行维度缩减。在为什么这个有用&#xff1f;已经可以在TF-IDF矢量器中使用“max_features”参数控制尺寸(特征)的数量。在我知道LSA(和LDA)也是主题建模技术。与聚类的区别在于&#xff0c;文档属于多个主题&#xff0c;但只属…...

温州做网站seo/2022网络热词30个

在程序开发过程中&#xff0c;我们时不时要用到一些定时器&#xff0c;通常如果时间精度要求不高&#xff0c;可以使用sleep&#xff0c;uslepp函数让进程睡眠一段时间来实现定时&#xff0c;前者单位为秒(s)&#xff0c;后者为微妙(us)&#xff1b;但有时候我们又不想让进程睡…...

深圳企业网站建设设计公司/百度公司电话

在科技日新月异的今天&#xff0c;我们已经习惯了身边的技术和产品&#xff0c;觉得这些技术就是生来就存在的&#xff0c;并不曾察觉到这些科技对人类发展、对我们的生活有什么样的改变。是否真的如此&#xff1f;以存储为例&#xff0c;刚刚结束的哥本哈根气候大会虽然并未形…...

曰本真人性做爰视频网站/北京seo运营推广

本篇博客从博客园上转载&#xff08;尊重作者&#xff09;&#xff1a; 作者&#xff1a;海子  出处&#xff1a;http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有&#xff0c;欢迎转载&#xff0c;但未经作者同意必须保留此段声明&am…...