Mysql--技术文档--MVCC(Multi-Version Concurrency Control | 多版本并发控制)

MVCC到底是什么

        MVCC(Multi-Version Concurrency Control)是一种并发控制机制,用于解决并发访问数据库时的数据一致性和隔离性问题。MVCC允许多个事务同时读取数据库的同一数据,而不会相互干扰或导致冲突。

        在传统的并发控制机制中,如锁定机制,事务会对读取和写入的数据进行加锁,以确保每个事务独占所需的资源。然而,这种悲观并发控制机制可能导致资源争用和性能问题,尤其是在高并发环境下。

一文读懂数据库的MVCC实现原理

 MVCC是innodb实现事务并发与回滚的重要功能!!!!!

MVCC解决了哪些问题

MVCC(Multi-Version Concurrency Control)解决了以下几个关键问题:

  1. 读-写冲突:传统的并发控制机制,如锁定机制,可能导致读取和写入操作之间的冲突。当多个事务试图同时读取和写入相同的数据时,会发生资源争用问题。MVCC通过并发控制的方式,让读取操作不受写入操作的干扰,从而避免了这种读-写冲突。

  2. 写-写冲突:在传统的并发控制机制中,当多个事务同时试图写入相同的数据时,会发生写入冲突。这可能导致数据的不一致性以及事务的回滚和重试。MVCC通过并发控制,使得每个事务都操作自己的独立版本,从而避免了写-写冲突,提高了并发性能。

  3. 隔离性问题:在多用户并发操作中,隔离性是确保事务之间互不干扰的重要属性。传统的并发控制机制,如锁定机制,可能导致事务之间的阻塞和相互等待。MVCC通过使用多个版本和快照读取,实现了事务之间的隔离性,使得事务可以并发执行而互不干扰。

  4. 性能问题:传统的并发控制机制中,加锁的方式可能导致较高的开销和资源争用,特别是在高并发环境下。MVCC采用了乐观的并发控制方式,减少了锁冲突和资源争用,从而提高了并发性能和系统吞吐量。

综上所述,MVCC通过解决读-写冲突、写-写冲突、隔离性问题和性能问题,提供了更好的并发控制机制。它通过版本管理和快照读取,使得多个事务可以并发执行而互不干扰,从而提高了数据库的性能、可用性和一致性。

MVCC底层机制-具体实现

具体的实现是,在数据库的每一行中,添加额外的三个字段:

  1. DB_TRX_ID – 记录插入或更新该行的最后一个事务的事务 ID
  2. DB_ROLL_PTR – 指向改行对应的 undolog 的指针
  3. DB_ROW_ID – 单调递增的行 ID,他就是 AUTO_INCREMENT 的主键 ID

在MVCC的实现中,使用乐观锁和额外的字段来实现并发控制。以下是对每个字段的具体解释和MVCC如何使用乐观锁的简单概述:

  1. DB_TRX_ID(事务ID):这个字段用于记录插入或更新行的最后一个事务的事务ID。每个事务在执行写操作时,都会生成一个唯一的事务ID并关联到相关数据行。这样,MVCC可以通过比较事务ID来确定事务执行期间的数据版本。

  2. DB_ROLL_PTR(undolog指针):这个字段指向对应行的undolog的指针。undolog是InnoDB存储引擎用于实现事务的撤销(undo)或回滚(rollback)操作的日志。通过保留undolog指针,MVCC可以在事务回滚或读取旧版本数据时进行快速回溯到适当的undolog。

  3. DB_ROW_ID(行ID):这个字段是单调递增的行ID,通常用作AUTO_INCREMENT主键ID。它提供了一种方式来唯一标识每一行,以便MVCC在处理并发操作时进行准确定位。

MVCC使用乐观锁来确保对数据行的并发访问不会产生冲突。它通过比较事务的启动时间戳(或序列号)和数据行的事务ID来判断是否存在并发冲突。当一个事务启动时,会获取所有需要读取或修改的数据行的版本信息,包括DB_TRX_ID和DB_ROLL_PTR字段。在读取或修改数据时,MVCC会使用这些版本信息进行验证,以确定是否访问的是合适的数据版本。

如果在事务执行期间,发现其他事务已经修改了数据行的版本(事务ID不一致),则会回滚当前事务,因为它访问的是过期的数据版本。这种方式可以避免读-写冲突和写-写冲突,提供了一致的数据访问和更新。

需要注意的是,MVCC的具体实现可能会有一些细微的差异,因为不同的数据库管理系统可能采用不同的方式来处理并发控制。但是上述提到的字段和基本思想是MVCC的常见实现方式之一。

总而言之,MVCC使用乐观锁和额外的字段来实现并发控制。通过比较事务ID和版本信息,MVCC可以识别并处理并发访问冲突,从而确保数据的一致性和隔离性。

悲观锁和乐观锁的对比

Mysql--技术文档--悲观锁、乐观锁-《控制并发机制简单认知、深度理解》_一单成的博客-CSDN博客

MVCC实现的三大要素

使用范围:

        首先要明白mvcc只在REPEATABLE READ(可重复读) 和 READ COMMITTED(已读提交)这两个隔离级别下面使用。

REPEATABLE(可重复的)、COMMITTED(承诺)

MVCC实现原理是两个隐式字段、undo日志、Read view来实现的。

1. 隐式字段

在Innodb存储引擎中,在有聚簇索引的情况下每一行记录中都会隐藏俩个字段,如果没有聚簇索引则还有一个6byte的隐藏主键。

这俩个隐藏列一个记录的是何时被创建的,一个记录的是什么时候被删除。

这里不要理解为是记录的是时间,存储的是事务ID。

俩个隐式字段为DB_TRX_ID,DB_ROLL_PTR,没有聚簇索引还会有DB_ROW_ID这个字段。

  • DB_TRX_ID:记录创建这条数据上次修改它的事务 ID
  • DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本

        隐式字段实际还有一个delete flag字段,即记录被更新或删除,这里的删除并不代表真的删除,而是将这条记录的delete flag改为true

        MySQL提供了逻辑删除的方式,可以通过在表中添加一个额外的列(例如delete_flag字段)来实现。逻辑删除是将记录标记为已删除的状态,而不是将其物理删除。这种方式保留了记录的历史信息,并且可以根据需要恢复或审计已删除的记录。在执行查询操作时,可以使用查询条件来过滤掉已标记为删除的记录。

2. undo log(回滚日志)

之前对undo log的作用只提到了回滚操作实现原子性,现在需要知道的另一个作用就是实现MVCC多版本控制器。

undo log细分为俩种,insert时产生的undo log、update,delete时产生的undo log

在Innodb中insert产生的undo log在提交事务之后就会被删除,因为新插入的数据没有历史版本,所以无需维护undo log。

update和delete操作产生的undo log都属于一种类型,在事务回滚时需要,而且在快照读时也需要,则需要维护多个版本信息。只有在快照读和事务回滚不涉及该日志时,对应的日志才会被purge线程统一删除。

purge线程会清理undo log的历史版本,同样也会清理del flag标记的记录。

undo log在mvcc中的作用

写到这里关于undo log在mvcc中的作用估计还是蒙圈的。

undo log保存的是一个版本链,也就是使用DB_ROLL_PTR这个字段来连接的。

当数据库执行一个select语句时会产生一致性视图read view

那么这个read view是由查询时所有未提交事务ID组成的数组,数组中最小的事务ID为min_id和已创建的最大事务ID为max_id组成,查询的数据结果需要跟read-view做比较从而得到快照结果。

所以说undo log在mvcc中的作用就是为了根据存储的事务ID和一致性视图做对比,从而得到快照结果。

3、undo log底层实现

在原始数据执行一条语句之后将undo log记录发生变化。

也就是说在一条语句更新的时候会把原有的数据拷贝到undo log日志中。

然后使用指针在最新的记录和旧的记录连接一条线,也就是存放undo log日志的指针地址。

最后需要的时候通过指针来找到历史数据。

Undo Log(回滚日志)是用于实现事务的原子性和一致性的一个重要组成部分。它是在事务执行期间记录数据修改操作的地方,并可用于回滚事务或恢复数据到之前的状态。

Undo Log的底层实现是通过使用一种称为"回滚段"的数据结构。回滚段是专门用于存储Undo Log的数据结构,它位于表空间中的一个特殊位置。

每个事务在执行修改操作前,会在Undo Log中为所涉及的数据行生成一个“回滚记录”。这个回滚记录存储了修改前的数据值(原始数据值),以及用于回滚操作的其他相关信息。

当事务需要回滚时,Undo Log可以通过相反的操作撤消该事务的修改。它会使用回滚记录中的原始数据值来将数据恢复到事务开始之前的状态。

此外,Undo Log还用于处理并发事务之间的读取一致性。在MVCC中,读取操作需要使用Undo Log来判断某个数据版本是否对当前事务可见。

总的来说,Undo Log的底层实现基于回滚段数据结构,它在事务执行期间记录数据的修改操作,并在事务回滚或 MVCC 快照读取时使用这些信息。这个机制确保了事务的原子性、一致性和隔离性,并为数据库提供了数据恢复和读取一致性的支持。

4、read-view

MySQL中的read-view(读视图)。在MySQL中,视图是一种虚拟表,它是根据一个或多个表的查询结果创建的。视图可以被看作是存储在数据库中的虚拟表格,可以像表一样查询和使用。

使用read-view可以实现以下功能:

  • 简化复杂的查询:通过创建视图,你可以将复杂的查询逻辑封装到一个简单的视图中,然后在查询中使用该视图,从而简化查询语句。

  • 访问权限控制:通过使用视图,你可以只向用户展示需要的数据,而隐藏底层表的细节。这提供了更好的安全性和数据访问控制。

  • 数据的逻辑组织:通过创建视图,你可以根据业务需求将表的数据进行组织和过滤,从而更好地管理和理解数据。

总之,read-view(读视图)是在MySQL中创建的一种虚拟表,可以用于简化查询、控制数据访问权限以及逻辑组织数据。

当执行SQL语句查询时会产生一致性视图,也就是read-view,它是由查询的那一时间所有未提交事务ID组成的数组,和已经创建的最大事务ID组成的。

在这个数组中最小的事务ID被称之为min_id,最大事务ID被称之为max_id,查询的数据结果要根据read-view做对比从而得到快照结果。

阿丹理解:

        这个概念其实就是在mysql中mvcc中的类似于快照的概念,因为innodb不是使用的是mvcc+乐观锁来解决并发问题嘛,对于操作进行锁不对读来锁,然后在进行操作的时候去对比之前的改之前的版本的。

        这个概念对于mvcc的作用是在一个事务开始时,它会根据自己的Read-View创建一个快照,并在整个事务期间使用这个快照进行读取操作。这个快照包含了事务开始时数据库的一个一致视图。

5、版本链对比规则

MVCC在MySQL中的实现底层包括以下几个组成部分:

  1. 版本链:每个数据行都有一个版本链,用于存储该数据行的多个版本。版本链可以是链表或者树形结构,具体的实现取决于MySQL的版本和存储引擎。版本链中的每个版本都包含了数据的实际内容以及相关的时间戳信息。

  2. 事务的时间戳:每个事务在开始时都会被分配一个时间戳。事务的时间戳用于判断每个版本对于该事务的可见性。

  3. 数据行的锁:为了保证并发事务的一致性,MySQL使用了锁机制。在MVCC中,数据行的读锁会阻止写事务对该数据行的修改操作,而写锁会阻止其他事务对该数据行的读写操作。

  4. 读取操作的一致性视图:每个事务在执行读取操作时会创建一个一致性视图。该一致性视图会基于事务的时间戳和数据行版本的时间戳来确定每个数据行对于该事务的可见性。

不同的存储引擎在MVCC的实现上可能会有细微的差异,因为存储引擎负责管理数据的存储和访问。例如,InnoDB存储引擎使用了undo日志和read-view机制来实现MVCC,而MyISAM存储引擎则没有内置的MVCC实现。

如果落在trx_id<min_id,表示此版本是已经提交的事务生成的,由于事务已经提交所以数据是可见的

如果落在trx_id>max_id,表示此版本是由将来启动的事务生成的,是肯定不可见的

若在min_id<=trx_id<=max_id时

  • 如果row的trx_id在数组中,表示此版本是由还没提交的事务生成的,不可见,但是当前自己的事务是可见的
  • 如果row的trx_id不在数组中,表明是提交的事务生成了该版本,可见

在这里还有一个特殊情况那就是对于已经删除的数据,在之前的undo log日志讲述时说了update和delete是同一种类型的undo log,同样也可以认为delete就是update的特殊情况。

当删除一条数据时会将版本链上最新的数据复制一份,然后将trx_id修改为删除时的trx_id,同时在该记录的头信息中存在一个delete flag标记,将这个标记写上true,用来表示当前记录已经删除。

在查询时按照版本链的规则查询到对应的记录,如果delete flag标记位为true,意味着数据已经被删除,则不返回数据。

 trx_id:

代表事务ID,用于标识每个事务的唯一性。它可以用于确定事务的开始时间和提交时间。

min_id:

最小可见事务ID。它表示正在执行的事务所能看到的最早提交的事务的ID。事务ID小于"min_id"的所有事务都是已经提交的事务,对于当前事务而言,它们的修改是可见的。

总结:

"trx_id"和"min_id"是MVCC中用于判断数据对于当前事务的可见性的重要标识。

注意:

对于已经删除的数据,在MVCC中会将最新版本的数据进行复制,并将"trx_id"修改为删除时的"trx_id"。同时,在记录的头信息中设置一个"delete flag"标记来表示该记录已经被删除。当查询时根据版本链的规则进行查询,如果"delete flag"标记为true,表示该数据已经被删除,因此不返回数据。

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

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

相关文章

基于Spring实现博客项目

访问地址:用户登录 代码获取:基于Spring实现博客项目: Spring项目写博客项目 一.项目开发 1.项目开发阶段 需求评审,需求分析项目设计(接口设计,DB设计等&#xff0c;比较大的需求,需要设计流程图&#xff0c;用例图,UML, model中的字段)开发&#xff0b;自测提测(提交测试…

DOM破坏绕过XSSfilter例题

目录 一、什么是DOM破坏 二、例题1 三、多层关系 1.Collection集合方式 2.标签关系 3.三层标签如何获取 四、例题2 五、例题3 1.代码审计 2.payload分析 一、什么是DOM破坏 DOM破坏&#xff08;DOM Clobbering&#xff09;指的是对网页上的DOM结构进行不当的修改&am…

Redis之GEO类型解读

目录 基本介绍 基本命令 geoadd 命令 geopos 命令 geodist 命令 georadius 命令 georadiusbymember 命令 geohash 命令 基本介绍 GEO 主要用于存储地理位置信息&#xff08;纬度、经度、名称&#xff09;添加到指定的key中。该功能在 Redis 3.2 版本新增。 GEO&…

C++炸弹小游戏

游戏效果 小人可以随便在一些元素&#xff08;如石头&#xff0c;岩浆&#xff0c;水&#xff0c;宝石等&#xff09;上跳跃&#xff0c;“地面”一直在上升&#xff0c;小人上升到顶部或者没有血的时候游戏结束&#xff08;初始20点血&#xff09;&#xff0c;小人可以随意放炸…

计算机网络MTU和MSS的区别

在计算机网络中&#xff0c;MTU代表最大传输单元&#xff08;Maximum Transmission Unit&#xff09;&#xff0c;而MSS代表最大分节大小&#xff08;Maximum Segment Size&#xff09;。 1.MTU&#xff08;最大传输单元&#xff09;&#xff1a; MTU是指在网络通信中&#x…

原神世界中的顺序表:派蒙的趣味数据结构讲解

派蒙&#xff0c;那个总是带着疑问眼神的小家伙&#xff0c;是原神世界中的小精灵。他总是充满好奇心&#xff0c;无论是对新的冒险者&#xff0c;还是对各种奇妙的现象。而他的另一个身份&#xff0c;则是原神世界中的数据结构大师。 一天&#xff0c;派蒙遇到了旅行者小森&a…

对开源自动化测试平台MeterSphere的使用感触

1&#xff1a;该平台可以通过接口&#xff0c;参数&#xff0c;配置的维护&#xff0c;然后继续接口自动化“一键测试”&#xff0c;功能还是挺强大的&#xff0c;具体的使用需要研究 MeterSphere的官网&#xff1a;MeterSphere - 专业测试云 2&#xff1a;一键测试在生产环境…

网络服务第二次作业

[rootlocalhost ~]# vim /etc/httpd/conf.d/vhosts.conf <Virtualhost 192.168.101.200:80> #虚拟主机IP及端口 DocumentRoot /www/openlab #网页文件存放目录 ServerName www.openlab.com #服务器域名 </VirtualHost> …

python实现/直播服务器/聊天服务器/的多种解决方案

python有哪些技术栈 实现直播服务器 在Python中&#xff0c;您可以使用以下技术栈来实现直播服务器&#xff1a; Flask&#xff1a;Flask是一个轻量级的Web框架&#xff0c;可用于构建直播服务器的后端。您可以使用Flask编写API端点来处理直播流的控制和管理。 Django&#xf…

两种数据库引擎和聚簇(非聚簇)索引

一&#xff1a;两种数据库引擎区别及如何选择&#xff1f; InnoDB和MyISAM的区别&#xff1f; 1&#xff1a;InnoDB支持事务&#xff0c;而MyISAM不支持事务。这是MYSQL将默认引擎从MYISAM变为INNODB的重要原因之一。 2&#xff1a;INNODB支持外键&#xff0c;而MYISAM不支持…

易云维®FMCS厂务系统创造工厂全新的“数字低碳智能”应用场景

近年来&#xff0c;新一代信息技术的高速发展为传统工业与制造业领域带来了新的机遇。信息技术加持下的制造技术发展出了新的生产方式、产业形态与管理模式。通过搭建FMCS厂务系统进行数字化转型来实现数据互联互通与业务高效协同&#xff0c;助力企业向安全、绿色、节能、高效…

上海港股通开通条件是什么?港股通交易佣金最低多少?

上海港股通权限开通条件有&#xff1a; 1、申请权限开通前20个交易日证券账户日均资产不低于50万元; 2、进行港股知识测试&#xff0c;且测试分数不低于80分; 3、风险承受能力等级需要匹配&#xff0c;无投资经验期限的门槛 港股通的股票范围是香港联合交易所恒生综合大型股…

MATLAB图论合集(二)计算最小生成树

今天来介绍第二部分&#xff0c;图论中非常重要的知识点——最小生成树。作为数据结构的理论知识&#xff0c;Prim算法和克鲁斯卡尔算法的思想此处博主不详细介绍&#xff0c;建议在阅读本帖前熟练掌握。 对于无向带权图&#xff0c;在MATLAB中可以直接以邻接矩阵的方式创建出来…

Flutter实现StackView

1.让界面之间可以嵌套且执行动画。 2.界面的添加遵循先进后出原则。 3.需要使用AnimateView&#xff0c;请看我上一篇博客。 演示&#xff1a; 代码&#xff1a; Stack: import package:flutter/cupertino.dart;///栈&#xff0c;先进后出 class KqWidgetStack {final Lis…

JVM知识点(一)

1、JVM基础概念 &#xff08;1&#xff09;JVM、JRE、JDK JRE&#xff1a;JVM基本类库组成的运行环境就是JRE。JVM自己是无法完成一次编译&#xff0c;处处运行的&#xff0c;需要有一个基本类库告诉JVM如何操作运行&#xff0c;如如何操作文件&#xff0c;连接网络等&#x…

JVM 给对象分配内存空间

指针碰撞空闲列表TLAB 为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。 指针碰撞&#xff1a;&#xff08;Bump The Pointer&#xff09; 堆的内存是绝对规整的&#xff0c;内存主要分为两部分&#xff0c;所有使用过的内存被放在一边&#x…

LeetCode每日一题:823. 带因子的二叉树(2023.8.29 C++)

目录 823. 带因子的二叉树 题目描述&#xff1a; 实现代码与解析&#xff1a; dp hash 原理思路&#xff1a; 823. 带因子的二叉树 题目描述&#xff1a; 给出一个含有不重复整数元素的数组 arr &#xff0c;每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树&#x…

达梦SQL书写注意事项

模糊查询 模糊查询like后面的字段要求用单引号引用&#xff0c;不能使用双引号 select * from user where name like %小组 分组查询 select查询的列字段必须在分组中的字段存在 正确&#xff1a; select name,age from user group by name,age 错误&#xff1a; select * f…

UE 透明物体绘制准备

PassProcessor注册&#xff1a; Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp透明的5个PassProcessor都继承BassPassProcessor。透明物质绘制&#xff0c;也是走的basepasspixelshader。 REGISTER_MESHPASSPROCESSOR_AND_PSOCOLLECTOR(BasePass, CreateBas…

华为OD机试 - MELON的难题 - 动态规划(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、动态规划五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 MELON有一堆精美的雨花石(数量为n&#xff0c;重量各异)&#xff0c;准备送给…