mysql mvvc原理_Mysql MVVC笔记

mysql mvvc原理_Mysql MVVC笔记什么是 MVVC 为什么要用它在 mysql 的也就是读不会加锁 举个不是很准确的例子 有两个事务 T1 T2 它们的 id 分别是 1 2 由于事务 id 是递增唯一的 因此可以认为 T2 在逻辑上是后于 T1 发生的 当 T2 想要查询 select 某一行 这行的 trx id 最后修改本行数据的事务 id 为 1 那么我们就可以认为这一行对 T2 是可见的 因此返回改行数据 其实这个例子问题很大 这也是为什么要写这篇文章记录一下

什么是MVVC,为什么要用它

在mysql的也就是读不会加锁。

举个不是很准确的例子,有两个事务T1,T2,它们的id分别是1,2。由于事务id是递增唯一的,因此可以认为T2在逻辑上是后于T1发生的,当T2想要查询(select)某一行,这行的trx_id(最后修改本行数据的事务id)为1,那么我们就可以认为这一行对T2是可见的,因此返回改行数据。

其实这个例子问题很大,这也是为什么要写这篇文章记录一下

前置知识

在InnoDB中,每个行后面都有一些额外的字段,主要要知道DB_TRX_ID(最近修改行的事务ID),DB_ROLL_PTR(指向该行被修改的前一个状态),DELETE_VERSION(行是否被删除)。

当某个事务T对一行R做update操作时,若R对T是可见的(判断方法放在后面讲),将该行的DELETE_VERSION置为T的id,并将改行放入undo log中,而在表中会插入一条新的行R’,R’的DB_TRX_ID为T的id,DELETE_VERSION为空,DB_ROLL_PTR指向刚刚被打入undo log的那行

修改前↓

00947240422ef6f2fdbebfc515b26167.png

修改后↓

336443784fb8803ff7abe73f668ed185.png

READ VIEW

其实ReadView可以理解成数据库中某个时间戳所有未提交事务的快照,ReadView类有这么几个参数:

m_ids:当前时间戳所有未提交的事务

min_trx_id:m_idx中最小的事务id

max_trx_id:当前时间戳InnoDB将在下一次分配的事务id

creator_trx_id:当前事务id

当创建一个ReadView对象时,也就知道了这个时间点上未提交事务的所有信息,从而能够通过这些信息实现锁的作用甚至增强。

有了这个ReadView,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:

如果被访问版本的trx_id属性值与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。

如果被访问版本的trx_id属性值小于ReadView中的min_trx_id值,表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问。

如果被访问版本的trx_id属性值大于或等于ReadView中的max_trx_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。

如果被访问版本的trx_id属性值在ReadView的min_trx_id和max_trx_id之间,那就需要判断一下trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。

正题

假如现在DBMS在处理三个事务,T2,T3,T5(T4已经提交了),那么开启下一个事务的时候,将会分配到一个id为6的id,也就是T6。现在T6要select这样一行:

dde50f21be69bc6bfc2bfef3c7bd21f3.png

首先会创建一个ReadView对象r:

r.m_ids=[T2,T3,T5],

r.min_trx_id=2,

r.max_trx_id=7

由于该行DB_TRX_ID=2, 而2!

如果该行是这样子的:

2b9fed8100fbc3140b0a27a47994cce8.png

由于1

又如果是:

bab038639a48fe5ca95478db51887e26.png

那就最后的改动就是在T6中进行的,也是对T6可见。

亦或是

e71e6d99494f64c398342b7fad421165.png

CPU调度嘛,人家虽然后来的但也可能先你下手了 。因此由于8>=r.max_trx_id=7,所以该行对T6不可见,找一下DB_ROLL_PTR指向的行,由于是空,返回0行。(如果不为空,那么对所指向的行对同样的可见性判断)

再者:

adc71de8cee8839ee6386d25d4975e65.png

虽然r.min_trx.id<=4

总结一下就是如下一个流程图:

de5e5d45ca8e30aca97983b11d1e9709.png

copy的,tmin,tmax,tid0分别对应r.min_trx.id,r.max_trx_id,DB_TRX_ID。

回到开头

有些博客写的是

7e1b6c940b598cf986a3f813732f2e61.png

如果以小于或等于当前事务版本号为依据来判断行的可见性,那么就会漏掉依然活跃未提交的事务,在RR隔离级别下会产生不可重复度(离谱)。

RR和RC的区别

READ COMMITTED —— 每次读取数据前都生成一个ReadView

REPEATABLE READ —— 在第一次读取数据时生成一个ReadView

Featrue plus

其实在这样的MVVC下,InnoDB在RR隔离级别下就能避免了幻读,原因是不管是后面新的事务还是已经存在的未提交事务,他们新增的数据行对当前事务都是不可见的,而已提交的事务又不可能新增行,妙啊

参考博客:

MVCC ReadView介绍

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225945.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午8:11
下一篇 2026年3月17日 上午8:11


相关推荐

  • Weblogic性能优化(图解)

    Weblogic性能优化(图解)

    2022年3月3日
    41
  • 2025最全Cursor高德MCP配置指南:10分钟实现智能地图功能【实战教程】

    2025最全Cursor高德MCP配置指南:10分钟实现智能地图功能【实战教程】

    2026年3月16日
    2
  • 修改select下拉菜单样式(input下拉框select)

    自带的select下拉菜单美观度实在不怎么样,并且不容易美化,当然我们可以模拟实现select下拉菜单,但是代码稍显复杂,不过也可以通过简单的CSS实现此效果,下面通过实例简单作一下介绍。代码如下:<!DOCTYPEhtml><html><head><metacharset=”utf-8″><metaname=”autho…

    2022年4月12日
    149
  • 一文读懂C++虚继承的内存模型

    一文读懂C++虚继承的内存模型一文读懂C++虚继承的内存模型1、前言2、多继承存在的问题3、虚继承简介4、虚继承在标准库中的使用5、虚继承下派生类的内存布局解析6、总结1、前言C++虚继承的内存模型是一个经典的问题,其具体实现依赖于编译器,可能会出现较大差异,但原理和最终的目的是大体相同的。本文将对g++中虚继承的内存模型进行详细解析。2、多继承存在的问题C++的多继承是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。从概念上来讲这是非常简单的,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突

    2022年6月7日
    32
  • h3c s2000交换机配置命令_华三两台交换机做dhcp

    h3c s2000交换机配置命令_华三两台交换机做dhcp
    一、 组网需求:
    Switch的端口Ethernet1/0/5与DHCP服务器端相连,端口Ethernet1/0/1,Ethernet1/0/2,Ethernet1/0/3分别与DHCPClientA、DHCPClientB、DHCPClientC相连。
    (1)在Switch上开启DHCPSnooping功能。
    (2)设置Switch上端口Ethernet1/0/5为DHCPSnooping信任端口。
    (3)在Switch

    2022年10月15日
    6
  • maven 打包 releases 和 snapshots 版本

    maven 打包 releases 和 snapshots 版本releases 线上版本 生产环境使用的 snapshots 快照版本 开发过程中使用的 maven 打包代码到私服根据 version 后面是否带有 SNAPSHOTS 来区分是打包线上版本还是快照版本 如果带有 SNAPSHOTS 打包快照版本 否则即为线上版本定义 version 使用占位符 在 properties 中设置默认 version 在 profiles 中根据

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号