MVCC实现原理

article/2025/11/9 23:27:09

1、什么是MVCC

mvcc多版本并发控制。

mvcc在mysql innodb中主要是为了提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突时,也能做到不加索,非阻塞并发读。。

2、实现原理:

mvcc的实现是通过保存数据在某个时间点的快照来实现的。也就是说不管需要执行多长时间,每个事物看到的数据都是一致的。

3、mvcc解决那些问题?

事务并发可能会产生以下问题:

  • 脏读:读取其它事务未提交的数据。
  • 不可重复读:一个事务在读取一条数据时,由于另一个事务修改了这条数据并且提交事务,再次读取时导致数据不一致
  • 幻读:一个事务读取了某个范围的数据,同时另一个事务新增了这个范围的数据,再次读取发现俩次得到的结果不一致。

mvcc可以解决脏读、不可重复读,使用快照读解决了部分幻读问题,但是在修改时还是使用当前读,所以还是存在幻读问题,幻读问题最终就是使用间隙锁解决。

4、当前读和快照读

当前读:给读操作加上共享锁、排它锁,DML操作加上排它锁,这些都是当前读。当前读所读取的数据都是最新的,读取数据时加上锁,保证其它事物不能修改当前记录。

快照读:快照读的数据有可能不是最新的,而是之前版本的数据。

如何区分当前读和快照读

不加锁的简单的select都属于快照读;与之对应的则是当前读,给select加上共享锁、排它锁。

5、mvcc底层实现要素

在这之前需要知道MVCC只在REPEATABLE READ(可重复读) 和 READ COMMITTED(已读提交)这俩种隔离级别下适用。

mvcc实现原理是通过 隐藏字段(创建时版本号、回滚指针、删除版本号)、undo log 、Read view来实现的。

5.1、隐藏字段

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

创建版本号:创建记录事务ID

删除版本号:删除/修改记录事务ID。这里只是将字段标记为删除状态。

回滚指针:指向记录上一个版本

5.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 保存一个版本链,也就是上面回滚指针字段连接的。

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

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

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

5.3、read view

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

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

于是就产生了以下的对比规则,这个规则就是使用当前的记录的trx_id跟read-view进行对比,对比规则如下。

5.3.1、版本链对比规则

如果落在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,意味着数据已经被删除,则不返回数据。

小结

在同一个事务中进行查询,会沿用第一次查询语句生成的read-view(前提是隔离级别是在可重复读)

通过以上的四个案例,在版本链寻找过程中,可以总结出一个小技巧

技巧图

根据这个小技巧你可以很快的得知此版本是否可见。

  • 如果当前的事务ID在绿色部分,是已经提交事务,则数据可见
  • 如果当前的事务ID在蓝色部分,会有俩种情况,如果当前事务ID在read-view数组内,是没有提交的事务不可见,如果不在数组内数据可见
  • 如果落在红色部分,则不考虑,对于未来的事情不去想即可。

总结

本文内容从浅到深,从什么是mvcc到mvcc的底层实现,一步一步地陈述了mvcc的实现原理。

本文简单总结

  • mvcc在不加锁的情况下解决了脏读、不可重复读和快照读下的幻读问题,一定不要认为幻读完全是mvcc解决的
  • 对当前读、快照读理解,简单点说加锁就是当前读,不加锁的就是快照读。
  • mvcc实现的三大要素俩个隐式字段、回滚日志、read-view
  • 俩个隐式字段:DB_TRX_ID:记录创建这条记录最后一次修改该记录的事务ID,DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本
  • undo log在更新数据时会产生版本链,是read-view获取数据的前提
  • read-view当SQL执行查询语句时产生的,是由为提交的事务ID组成的数组和创建的最大事务ID组成的
  • 版本链规则看第五节的小结即可

 


http://chatgpt.dhexx.cn/article/jItg8Pmj.shtml

相关文章

MySQL的MVCC及实现原理

一 概要 1.什么是 MVCC ? MVCC&#xff0c;全称 Multi-Version Concurrency Control &#xff0c;即多版本并发控制。MVCC 是一种并发控制的方法&#xff0c;一般在数据库管理系统中&#xff0c;实现对数据库的并发访问&#xff0c;在编程语言中实现事务内存。 MVCC 在 MySQL…

InnoDB MVCC 机制

本文详细的介绍了什么是MVCC&#xff1f;为什么要有MVCC&#xff1f;以及MVCC的内部实现原理&#xff1a;包括Undo Log的版本链是如何组织的&#xff0c;RR、RC两个级别下一致性读是如何实现的等。通过案例、插图&#xff0c;以最通俗易懂的方式&#xff0c;让你彻底掌握MVCC的…

mysql mvcc 实例说明_Mysql MVCC

一、MVCC概述 MVCC&#xff0c;全称Multi-Version Concurrency Control&#xff0c;即多版本并发控制。整个MVCC多并发控制的目的就是为了实现读-写冲突不加锁&#xff0c;提高并发读写性能&#xff0c;而这个读指的就是快照度, 而非当前读&#xff0c;当前读实际上是一种加锁的…

MVCC

一、什么是MVCC MVCC&#xff08;Multiversion concurrency control &#xff09;是一种多版本并发控制机制。 二、MVCC是为了解决什么问题? 并发访问(读或写)数据库时&#xff0c;对正在事务内处理的数据做多版本的管理。以达到用来避免写操作的堵塞&#xff0c;从而引发读操…

MVCC详解

一、前言 全称Multi-Version Concurrency Control&#xff0c;即多版本并发控制&#xff0c;主要是为了提高数据库的并发性能。以下文章都是围绕InnoDB引擎来讲&#xff0c;因为myIsam不支持事务。 同一行数据平时发生读写请求时&#xff0c;会上锁阻塞住。但mvcc用更好的方式…

MVCC 机制的原理及实现

什么是 MVCC MVCC (Multiversion Concurrency Control) 中文全程叫多版本并发控制&#xff0c;是现代数据库&#xff08;包括 MySQL、Oracle、PostgreSQL 等&#xff09;引擎实现中常用的处理读写冲突的手段&#xff0c;目的在于提高数据库高并发场景下的吞吐性能。 如此一来…

深入浅出:MVCC详解

什么是MVCC&#xff1a; MVCC(Multi Version Concurrency Control的简称)&#xff0c;代表多版本并发控制。与MVCC相对的&#xff0c;是基于锁的并发控制&#xff0c;Lock-Based Concurrency Control)。 MVCC最大的优势&#xff1a;读不加锁&#xff0c;读写不冲突。在读多写少…

什么是MVCC?MVCC解决了什么问题?MVCC的实现原理?

1.什么是MVCC&#xff1f; MVCC全称是【Multi-Version ConCurrency Control】&#xff0c;即多版本控制协议。 多版本控制&#xff08;Multiversion Concurrency Control&#xff09;: 指的是一种提高并发的技术。最早的数据库系统&#xff0c;只有读读之间可以并发&#xff…

MVCC详解,深入浅出简单易懂

一、什么是MVCC&#xff1f; mvcc&#xff0c;也就是多版本并发控制&#xff0c;是为了在读取数据时不加锁来提高读取效率和并发性的一种手段。 数据库并发有以下几种场景&#xff1a; 读-读&#xff1a;不存在任何问题。读-写&#xff1a;有线程安全问题&#xff0c;可能出…

【MySQL笔记】正确的理解MySQL的MVCC及实现原理

MVCC多版本并发控制 如果觉得对你有帮助&#xff0c;能否点个赞或关个注&#xff0c;以示鼓励笔者呢&#xff1f;&#xff01;博客目录 | 先点这里 &#xff01;首先声明&#xff0c;MySQL 的测试环境是 5.7 前提概要 什么是 MVCC什么是当前读和快照读&#xff1f;当前读&…

Oracle自定义函数

使用Navicat的话&#xff0c;可以点击函数&#xff0c;新建函数&#xff0c;根据引导完成一个函数的基本搭建。 语法和Java类似&#xff0c;其中对于变量赋值要使用 : 进行赋值。 具体语法可以参考一下 Oracle 自定义函数语法与实例_桑汤奈伊伏的博客-CSDN博客_oracle 自定义函…

Oracle 创建函数

Oracle创建函数是通过PL/SQL自定义编写的&#xff0c;通过关键字function按照自己的需求把复杂的业务逻辑封装进PL/SQL函数中&#xff0c;函数提供一个返回值&#xff0c;返回给使用者。这样使用者就不需要去理解业务逻辑&#xff0c;把PL/SQL函数中的业务逻辑交给专门的开发人…

Oracle函数的使用

在进行select查询的时候&#xff0c;可以为列指定函数&#xff0c;函数是sql语句中的一个非常有用的特性&#xff0c;oracle内置了用于处理字符&#xff0c;数字&#xff0c;日期及转换的各种函数&#xff0c;使用函数能够执行数据计算&#xff0c;修改列数据的显示&#xff0c…

Oracle函数【详细 包括举例】

概述 Oracle SQL 提供了用于执行特定操作的专用函数。这些函数大大增强了 SQL 语言的功能。函数可以接受零个或者多个输入参数&#xff0c;并返回一个输出结果。 Oracle 数据库中主要使用两种类型的函数&#xff1a; 1. 单行函数&#xff1a;对每一个函数应用在表的记录中时&a…

Oracle 函数编写

CREATE OR REPLACE FUNCTION f_homestay_count (wkt_poly CLOB ) RETURN NUMBER IS result NUMBER ; BEGINSELECTCOUNT (*) INTO resultFROMHOMESTAY_BASIC TWHEREsdo_anyinteract (T .geom_point,sdo_geometry (wkt_poly, 4326)) TRUE; RETURN (result) ;END ;因为之前都是…

Oracle 自定义函数

语法结构 CREATE [OR REPLACE] FUNCTION 定义的函数名称(参数名1 参数类型,参数名2 参数类型, ...) RETURN 返回值类型 AS/IS 返回值形参 形参类型实例化 BEGIN 方法体 &#xff08;其中用到if判断的话&#xff0c;每一个if对应一个end if&#xff0c;出现几次if就会有几个end…

oracle常用函数

1.sign sign函数是根据给的数为正数&#xff0c;就返回1,0返回0&#xff0c;负数返回-1。需要注意sign&#xff08;这个括号里面只能是个字段&#xff09;&#xff0c;在括号中写个子查询直接就报错了&#xff01; 2.decode 用法&#xff1a; decode(条件,值1,返回值1,值2,返回…

Oracle(四)Oracle 函数

目录 函数介绍Oracle字符型函数Oracle日期型函数系统日期、时间函数&#xff1a;数据库时区函数&#xff1a;给日期加上指定的月份函数&#xff1a;月份最后一天函数:指定日期后一周的日期函数:返回指定日期中特定部分的函数&#xff1a;返回两个日期间的月份数&#xff1a;日期…

oracle函数instr函数

1 instr函数的概念 在Oracle中可以使用instr函数对某个字符串进行判断&#xff0c;判断其是否含有指定的字符。在一个字符串中查找指定的字符,返回被查找到的指定 的字符的位置。 2 语法 instr(sourceString,destString,start,appearPosition) instr&#xff08;‘源字符串’,‘…

Oracle常用函数【建议收藏】

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;目前从事DBA及程序编程 &#xff08;Web\java\Python&#xff09;工作&#xff0c;主要服务于生产制造 现拥有 Oracle 11g OCP/OCM、 Mysql、Oceanbase&#xff08;OBCA&#xff09;认证 分布式TBase\TDSQL数据库、国…