【MySQL】MVCC详解与MVCC实现原理(MySQL专栏启动)

news2024/10/5 18:30:15

📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

  

🏆 InfoQ签约作者、CSDN专家博主/后端领域优质创作者/内容合伙人、阿里云专家/签约博主、51CTO专家 🏆

  

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~ 

本文目录

本文导读

一、什么是MVCC

二、MVCC的实现原理

1、MVCC多版本实现

2、MVCC 实现原理

3、什么是 Read View

3.1、Read View 解析

3.2、Read View 含义

3.3、Read View 如何判断版本链可用

三、当前读,快照读与MVCC

1、什么是当前读和快照读

1.1、当前读

1.2、快照读

2、快照读、当前读与MVCC辨析

3、MVCC 只在 RC 和 RR 隔离级别下工作

总结


本文导读

本文是:MySQL事务隔离机制与实现原理详解,的深入学习,我们在了解MySQL事务隔离机制与实现原理后,了解什么是MVCC,MVCC的实现原理,最后辨析当前读和快照读与MVCC和事务隔离的关系,更加全面和深入的MySQL事务隔离机制。

一、什么是MVCC

MVCC,全称 Multi-Version Concurrency Control ,MVCC是多版本并发控制的全称,是指多版本的并发控制。MVCC是一种并发控制方法。通常,在数据库管理系统中,它用编程语言实现对数据库和事务存储器的并发访问。

MVCC 是一种在读取数据时无需锁定(加锁)即可提高读取效率和并发性的方法。

数据库并发有以下情况:

1、读-读:没有问题。

2、读-写:存在线程安全问题,这可能导致脏读、幻读和不可重复读。

3、写-写:存在线程安全问题,更新可能会丢失。

二、MVCC的实现原理

首先我们回顾:MySQL事务隔离机制与实现原理详解

这里面讲解了,事务的特性、事务的隔离级别,当时说MySQL事务实现原理有单版本控制——锁,以及多版本控制MVCC。

现在我们需要知道,在读已提交RC,Read Committed)和可重复读RR,Repeatable Read)隔离级别下的快照读,都是基于MVCC实现的!

MVCC最大的优点是没有读锁,读写之间没有冲突。在读多写少的OLTP(On-Line Transaction Processing,联机事务处理)应用程序中,读写之间没有冲突非常重要,这大大提高了系统的并发性。

1、MVCC多版本实现

为了让您更直观地理解MVCC的实现原理,这里通过事务更新一行记录的过程的例子,来解释MVCC中多个版本的实现。

假设 ID~……是表中字段的名称(DATA)。最后三个隐藏字段对应对应行的隐藏ID、事务编号和回滚指针,如下图所示:

隐含ID(DB_ROW_ID),6字节,当InnoDB自动生成聚集索引时,聚集索引包括这个DB_ROW_ ID的值。

事务编号(DB_TRX_ID),6字节,它标记了此行最新更新记录的事务ID。每个事务都被处理,其值自动为+1。

回滚指针(DB_ROLL_PT),7个字节,指向当前记录项的回滚段的撤消日志记录,通过该记录可以找到以前版本的数据。

具体更新过程简述如下:

首先,如果数据只是INSERT,则可以认为ID是 1,其他两个字段为空。

当 事务1 更改此行的数据值时,将执行,一、使用独占锁锁定行,记录重做日志;二、将修改前这一行的值复制到Undo日志;三、修改当前行的值,填写事务ID,并使回滚指针指向撤销日志中修改前的行。

接下来,与 事务1 相同。此时,undo 日志中有两行记录,它们由回滚指针连接。

因此,如果撤消日志没有一直被删除,那么当前记录的回滚指针将追溯到创建该行时的初始内容。InnoDB中有一个清除线程,将查询比最旧的活动事务更早的撤消日志并将其删除,从而确保撤消日志文件不会无限增长。

2、MVCC 实现原理

它的实现原理主要是依赖记录中的 3个隐式字段(DB_ROW_ID、DB_TRX_ID、DB_ROLL_PT),undo日志 , Read View 来实现的。

上面我们已经详细介绍了3个隐式字段的含义,总结一下

默认情况下,DB_ROW_ID 是数据库为这行记录生成的唯一隐式主键。DB_TRX_ID 是当前操作记录的事务ID,而 DB_ROLL_PTR 是一个回滚指针,与撤消日志一起使用以指向以前的旧版本。

有两种 undo 日志:insert undo log、update undo log,帮助MVCC的撤销的本质是update undo log 。事实上,撤消日志是回滚段中的旧记录链。(MySQL日志系统的详解:(待补充))。

3、什么是 Read View

什么是 Read View

Read View  是事务执行快照读取操作时生成的视图。在事务执行快照读取时,将生成数据库系统的当前快照,并记录和维护系统当前活动事务的ID(当每个事务启动时,将分配一个ID,该ID是增量的,因此最新事务的ID值更大)。

当我们使用select读取数据时,此时会有许多版本的数据,但我们不知道要读取哪个版本。

此时,我们依赖readview来限制我们可以读取的版本。只有通过readview才能知道我们可以阅读哪个版本。

3.1、Read View 解析

Read View主要用于进行可见性判断,也就是说,当我们为事务执行快照读时,我们会为记录创建一个读取视图 Read View。以判断当前事务可以看到哪个版本的数据。它可能是当前期间的最新数据,也可能是记录 undo log 中某个版本的数据。

读取视图遵循可见性算法,主要是要修改的数据的最新记录中的 DB_TRX_ID (即当前事务ID),并与系统中其他活动事务的ID(由读取视图 Read View 维护)进行比较。

如果 DB_TRX_ID 跟 Read View 属性不符合可见性,通过 DB_ROLL_PTR 回滚指针在撤消日志Undo Log中的 DB_TRX_ID 比较中检索数据库(遍历链表的 DB_TRX_ID)。

遍历链接列表的DB _ TRX_ ID(从链的开始到链的结束,即从最近的修改),直到找到满足特定条件的 DB_TRX_ID , 那么这个 DB_TRX_ID 所在的旧记录就是当前事务能看见的最新老版本。

3.2、Read View 含义

在一个 Read View 快照中主要包括以下这些字段:

m_ids,表示生成 Read View 时当前系统中活动读/写事务的事务ID列表

min_trx_id,表示生成 Read View 时当前系统中活动读/写事务中最小的事务ID,即 m_ids 最小值

max_trx_id,表示生成 Read View 时应分配给系统中下一个事务的ID值

creator_trx_id,表示生成 Read View 的事务的事务ID

3.3、Read View 如何判断版本链可用

trx_id == creator_trx_id,可以访问这个版本;

trx_id < min_trx_id,可以访问这个版本;trx_id > max_trx_id,不可以访问这个版本;

min_trx_id <= trx_id <= max_trx_id,如果 trx_id 在 m_ids 中不可以访问,反之可以

三、当前读,快照读与MVCC

1、什么是当前读和快照读

1.1、当前读

select lock in share mode (共享锁), select for update; update; insert; delete (排他锁)这些操作都是一种当前读。

它读取最新版本的记录,读取时,它还确保其他并发事务无法修改当前记录,并锁定读取的记录。

1.2、快照读

不加锁的 select 操作就是快照读,即无锁的非阻塞读取;

快照读的前提是隔离级别不是串行级别,在串行级别下读取的快照将退化为当前读取,发生快照读的原因是基于提高并发性能的考虑。

快照读的实现基于多版本并发控制,即MVCC。MVCC可以被认为是行锁的变体,但在许多情况下,它避免了锁操作并减少了开销;由于它基于多个版本,也就是说,读取的快照可能不是数据的最新版本,而是以前的历史版本

MVCC的设计目的是在不锁定读写冲突,这种读取指的是快照读取,而不是当前读取。

当前的读取实际上是一个锁操作,这是悲观锁的实现

2、快照读、当前读与MVCC辨析

MVCC多版本并发控制的概念是“维护一个数据的多个版本,以便读写操作之间没有冲突”。

因为MVCC只是一个抽象的概念,为了实现这样的概念,MySQL需要提供特定的功能来实现它。“快照读取是MySQL MVCC理想模型的非阻塞读取功能之一”。

相对而言,当前读是悲观锁的具体功能实现,快照阅读本身也是一个抽象概念。

3、MVCC 只在 RC 和 RR 隔离级别下工作

一、 在RC(Read Commited )的隔离级别下,每次快照读取都会生成并获得最新的 readview

二、在RR(Repeatable Read)隔离级别,只有读取同一事务的第一个快照才能创建 readview。每个后续快照读取都使用相同的 readview,因此每个查询结果都相同。

总结

本文是:MySQL事务隔离机制与实现原理详解,的深入学习,我们在了解MySQL事务隔离机制与实现原理后,了解什么是MVCC,MVCC的实现原理,最后辨析当前读和快照读与MVCC和事务隔离的关系,更加全面和深入的MySQL事务隔离机制。

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

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

相关文章

Vue2 Element | 一文带你快速搭建网页界面UI

&#x1f451; 博主简介&#xff1a;    &#x1f947; Java领域新星创作者    &#x1f947; 阿里云开发者社区专家博主、星级博主、技术博主 &#x1f91d; 交流社区&#xff1a;BoBooY&#xff08;优质编程学习笔记社区&#xff09; 前言&#xff1a;在学习本篇文章内容…

Cholesterol胆固醇丨艾美捷Cholesterol胆固醇化学性质

胆固醇是由甾体部分和一条长的侧链组成。人体中胆固醇的总量大约占体重的0.2%&#xff0c;每100克组织中&#xff0c;骨质约含10毫克&#xff0c;骨骼肌约含100毫克&#xff0c;内脏多在150~250毫克之间&#xff0c;肝脏和皮肤含量稍高&#xff0c;约为300毫克。脑和神经组织中…

【JVM学习笔记】JVM内存区域定义与内存结构

目录定义和说明JVM内存区域的定义内存区域说明堆说明非堆-方法区说明堆栈的区别HotSpot虚拟机JVM线程独占内存程序计数器&#xff1a;Program Counter RegisterJava虚拟机栈&#xff1a;Java Virtual Machine Stack本地方法栈&#xff1a;Native Method StackJVM共享内存Java堆…

Arduino与Proteus仿真实例-密码门禁控制仿真

密码门禁控制仿真 1、应用介绍 本文将演示如何实现密码门禁控制逻辑仿真。 此次仿真主要涉及如下内容: 密码输入、更新、验证门禁控制逻辑此次仿真将使用继电器和直流电机作为电子门禁元件仿真器件。 在前面的文章中,对密码输入、更新、验证、储存,做了详细的仿真,请参…

API:低代码平台的秘诀

应用编程接口 (API) 是应用程序以可编程格式访问其关键能力和功能的一种方式&#xff0c;从而其他应用程序可以利用它们。API 本质上支持应用程序之间的无缝数据流&#xff0c;使开发人员能够在应用程序中添加更多功能&#xff0c;而无需依赖大量编码。 举一个简单的例子。 您…

实战!接口优化的18种方案

前言 大家好&#xff0c;我是捡田螺的小男孩。 之前工作中&#xff0c;遇到一个504超时问题。原因是因为接口耗时过长&#xff0c;超过nginx配置的10秒。然后 真枪实弹搞了一次接口性能优化&#xff0c;最后接口从11.3s降为170ms。本文将跟小伙伴们分享接口优化的一些通用方案…

maven如何手动添加jar包到本地仓库

1 下载需要添加的jar包 可以在maven库中查找下载&#xff0c;也可以在对应官网下载 maven库网址 2 第二步&#xff1a;将下载的jar包放到指定位置&#xff08;位置自己指定&#xff09; 3 第三步&#xff1a;配置本地maven库 &#xff08;1&#xff09;首先检查本地maven库…

结构优化软件SolidThinking Inspire的自学攻略

作者&#xff1a;孙一凡&#xff0c;仿真秀专栏作者 2004年上大学那会&#xff0c;ANSYS软件推广应用还没现在这么广泛&#xff0c;有个老师接项目就是用ANSYS计算&#xff0c;觉得很是高大上&#xff01;ABAQUS还是一个小众软件&#xff0c;甚至一本参考资料书籍都买不到。短…

前端一面经典react面试题(边面边更)

react 的虚拟dom是怎么实现的 首先说说为什么要使用Virturl DOM&#xff0c;因为操作真实DOM的耗费的性能代价太高&#xff0c;所以react内部使用js实现了一套dom结构&#xff0c;在每次操作在和真实dom之前&#xff0c;使用实现好的diff算法&#xff0c;对虚拟dom进行比较&…

SVM与基于马氏距离的径向基函数(MDRBF)核结合组合(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Scala 数组

Scala 语言中提供的数组是用来存储固定大小的同类型元素&#xff0c;数组对于每一门编辑应语言来说都是重要的数据结构之一。 声明数组变量并不是声明 number0、number1、...、number99 一个个单独的变量&#xff0c;而是声明一个就像 numbers 这样的变量&#xff0c;然后使用…

【设计模式】建造者模式

1. 概述 建造者模式将复杂产品的创建步骤分解在不同的方法中&#xff0c;使得创建过程更加清晰&#xff0c;从而更精确控制复杂对象的生产过程&#xff1b; 通过隔离复杂对象的构建与使用&#xff0c;也就是将产品的创建与产品本身分离开来&#xff0c;使得同样的构建过程可以…

Python编程从入门到实践 第七章:用户输入和while循环 练习答案记录

Python编程从入门到实践 第七章&#xff1a;用户输入和while循环 练习答案记录 练习题导航Python编程从入门到实践 第七章&#xff1a;用户输入和while循环 练习答案记录7.1 函数input()的工作原理7.1.1 编写清晰的程序7.1.2 使用int()来获取数值输入7.1.3 求模运算符练习7-1 汽…

SpringMVC学习篇(十)

springmvc拦截器之重复提交 1 出现原因 在新增和修改界面点击提交后(转发的方式跳转) 再次刷新页面,如果不做处理的话,会造成重复提交, 从而使得新增商品多次或者更改商品多次2 解决方案 2.1 准备工作 导入servlet-api依赖和spring-webmvc依赖 <dependency><group…

限流的几种方式及简单实现

文章目录计数器信号量滑动窗口漏桶令牌桶测试示例代码计数器 计数器限流方式比较粗暴&#xff0c;一次访问就增加一次计数&#xff0c;在系统内设置每 N 秒的访问量&#xff0c;超过访问量的访问直接丢弃&#xff0c;从而实现限流访问。 具体大概是以下步骤&#xff1a; 将时…

Spring Security认证之登录用户数据获取

本文内容来自王松老师的《深入浅出Spring Security》&#xff0c;自己在学习的时候为了加深理解顺手抄录的&#xff0c;有时候还会写一些自己的想法。 登录用户数据获取 登录成功之后&#xff0c;在后续的业务逻辑中开发者可能还需要获取到登录成功的用户对象&#xff0c;如果不…

轻松学会JavaScript事件

文章目录事件与事件流事件监听&#xff08;绑定事件方法&#xff09;JavaScript事件鼠标事件表单事件键盘事件UI事件快速投票事件可以说是JavaScript最引人注目的特性&#xff0c;因为它提供了一个平台&#xff0c;让用户不仅能浏览页面中的内容&#xff0c;而且能跟页面进行交…

贪心算法+动态规划 | 眼光不同决定深度不同

前言 上大学那会有门课程叫做【算法与实践】, 算法配上 C 那感觉不要提多爽了。现在回想起来算法不局限于语言&#xff0c;只不过每个语言的语法不一罢了&#xff0c; 但是算法的内在逻辑都是相通的&#xff0c;今天我们通过三个案列来了解分析下算法之一 【贪心算法】。 简介…

显示控件——滑动选择

该控件也是一种调节控件&#xff0c;通过在既定范围内的滑动来选择具体选项值以图达到对变量的调控效果&#xff0c;其UI操作效果类似于拨动密码锁的滚轮。 位置信息&#xff1a;控件在工程页面区域的位置 “X”“Y”为控件区域左上角坐标。 “W”“H”为控件区域宽度和高度&a…

cpu设计和实现(取指)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 cpu设计的本质是数字电路的设计。要是没有verilog、vhdl这些语言&#xff0c;那么剩下来使用的方法基本只有卡诺图这一种了。在数字电路中&#xf…