MVCC机制

article/2025/11/9 23:18:45

MVCC

1. MVCC是什么?

MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。 MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView

2. 当前读和快照读

  • 当前读

当前读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:

select * from test lock in share mode; # (共掌锁)
select* from test for update; # (排他锁)
# update、insert、delete等DML语言也会加排它锁,造成当前读
  • 快照读

    • Repeatable Read(可重复度隔离级别):开启事务后第一个selecti语句才是快照读的地方。

    • Read Committed(读提交隔离级别):每次select,都生成一个快照读。

简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。

3.MVCC实现原理

对于每一个数据库中的数据都会创建 3 个隐藏字段,包括 db_trx_id、db_roll_pointer、db_row_id。其中 db_trx_id 代表的是本次事务的id,db_roll_pointer 代表的是上一个已提交事务的地址,db_row_id 只有当该表不存在主键时才会创建。

在这里插入图片描述

undo log 调用链,undo log 会保存每一次对数据库的修改,用来保证输事务回滚。其中链表的尾部代表的是最新的修改,链表的首部代表的是最早的旧记录。

其中由于 select 不会对数据进行修改,所以 select 不会添加 undo log 日志。只有进行 DML 操作的时候才会有 undo log

  • Insert :插入一条记录时,至少要把这条记录的主键值记下来,之后回滚的时候只需要把这个主键值对应的记录删掉就好了。

  • Update :修改一条记录时,至少要把修改这条记录前的旧值都记录下来,这样之后回滚时再把这条记录更新为旧值就好了。

  • Delete :删除一条记录时,至少要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中就好了。 删除操作的时候,会有一个逻辑删除的字段 DELETED_BIT,将其置为 true 并不是真正的删除

为了节省磁盘空间,InnoDB有专门的purge线程来清理DELETED_BIT为true的记录。为了不影响MVCC的正常工作,purge线程自己也维护了一个read view(这个read view相当于系统中最老活跃事务的read view);如果某个记录的DELETED_BIT为true,并且DB_TRX_ID相对于purge线程的read view可见,那么这条记录一定是可以被安全清除的。

在这里插入图片描述

4. readView

InnoDB的默认隔离级别是可重复读,所以在该事务之前且提交的数据改变是可见的,该事务之后的数据改变不可见。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVLDfcJI-1669391753167)(images/image-20221125225734637.png)]

如图所示,如果该线程开启的事务 id 为 20,那么在 20 之前且提交的事务都是可见的,在 20 之后的事务都是不可见的。不过MySQL进行优化,用一个 readView 来存放当前的活跃事务。

在这里插入图片描述

如上图所示,事务 20,对于事务 7 以前的都是可见的,但是对于事务 7 、事务 9 和事务 11 是不可见的,因为他们是活跃的事务,还没有提交。对于事务20以后是不可见的,因为肯定会大于 20 。

5. 可重复读原理

可重复读就是利用了这样的一个思想,当进行第一次快照时,变回构建视图。

在这里插入图片描述

如上图,当开启事务 20 视图列表就会构建好。但是进行当前读的会重新构建视图。

思考

事务 9 对表中字段进行修改当前读能看到吗?如果能看到,那岂不是违背了可重复读?

答:在进行第一次快照读建立视图之后,以后所有快照读都会使用这个视图。而当前读是可以看到之前提交的内容。下面是我做的一个实验,可以看出很容易出现莫名其妙的BUG,比如我只想加 1 ,但是最后却加了 2 。如果此时采用 where 条件去筛选很可能会发生意料之外的错误。

事务1事务2
begin;
begin;
select * from product; # (price = 5000)
update product set price = price+1 where pid=1;
commit;
select * from product lock in share mode; # (price = 5001)
select * from product; # (price = 5000)
update product set price = price+1 where pid=1;
select * from product; # (price = 5002) 自己的修改是可见的

6. 读提交

了解了可重复读之后,读提交其实比较容易理解,就是每一次select之后都进行一次视图重建。下面是采用读提交的过程。

事务1事务2
begin;
begin;
select * from product; # (price = 5000)
update product set price = price+1 where pid=1;
commit;
select * from product lock in share mode; # (price = 5001)
select * from product; # (price = 5001)
update product set price = price+1 where pid=1;
select * from product; # (price = 5002) 自己的修改是可见的

引用

https://pdai.tech/md/db/sql-mysql/sql-mysql-mvcc.html#%E4%BB%80%E4%B9%88%E6%98%AFmvcc
《MySQL实战45讲》
https://www.bilibili.com/video/BV1Kr4y1i7ru


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

相关文章

MVCC实现原理

1、什么是MVCC mvcc多版本并发控制。 mvcc在mysql innodb中主要是为了提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突时,也能做到不加索,非阻塞并发读。。 2、实现原理: mvcc的实现是通过保存…

MySQL的MVCC及实现原理

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

InnoDB MVCC 机制

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

mysql mvcc 实例说明_Mysql MVCC

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

MVCC

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

MVCC详解

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

MVCC 机制的原理及实现

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

深入浅出:MVCC详解

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

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

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

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

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

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

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

Oracle自定义函数

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

Oracle 创建函数

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

Oracle函数的使用

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

Oracle函数【详细 包括举例】

概述 Oracle SQL 提供了用于执行特定操作的专用函数。这些函数大大增强了 SQL 语言的功能。函数可以接受零个或者多个输入参数,并返回一个输出结果。 Oracle 数据库中主要使用两种类型的函数: 1. 单行函数:对每一个函数应用在表的记录中时&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 方法体 (其中用到if判断的话,每一个if对应一个end if,出现几次if就会有几个end…

oracle常用函数

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

Oracle(四)Oracle 函数

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

oracle函数instr函数

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