mysql事务 mvcc

MySQL -MVCC

image-20220530132506184

在innoDB引擎中 有隐式字段,来标记每一行数据的版本(riwtrx_id),同时还有一个字段指向上一个版本的内存地址值。

图上是一行数据的4个版本。 V4版本 值是22,transaction id 为25的事务更新,rowtrx_id 是25

v1-v3 在物理上并不存在,而是每次需要的时候根据当前版本,和undo log计算出来。

InnoDB为每一个事务构造了一个数组(数组最ID值为低水位,系统里已经创建的事务ID最大值+1 为高水位),用来保存这个事务启动的瞬间,数据的可见性规则,就是基于数据的rowtrx_id和这个一致性性视图(read-view)的对比结果得到的

image-20220530133432000

  1. 以提交事务: 这个版本是已经提交的事务或者是当前事务自己生成的,这个数据是可见的
  2. 未提交事务集合:
    1. rowtrx_id ; 在数组中,这个版本是还没提交的事务生成的,不可见。
    2. rowtrx_id:不再数组中,这个版本是已经提交了的事务生成的,可见。
  3. 未开始事务: 这个版本是由将来启动的事务生成的,是肯定不可见的。

例如:上图中 如果低水位为 18 ,那么它访问这一行数据时,就从V4 通过 U3 计算出 V3 读取的值时11。

image-20220530153012296

历史 90 事务版本 (id =1 , value= 1)

在事务C(102)中,把数据从 value =1 改为 value =2,rowtrx_id时102提交的

在A(100)查询的时候 它的视图数组是 [99,100],所以读取数据要从当前版本开始读。

在可重复读隔离级别下, 只要事务开始读时候创建一致性视图,之后事务里的其他查询都 共用这个一致性视图

在读提交隔离级别下,每一个语句执行钱都会重新算出一个新的视图

  • 读取流程

    • 查询结果 rowtrx_id = 101 比高水位大,处于未开始事务,不可见版本
    • 查询上一个历史版本,rowtrx_id = 102 ,处于未开始事务,不可见版本
    • 查询上一个历史版本,rowtrx_id = 90 , 低水位,已提交事务,可见

这样执行,虽然期间这一行数据被修改过,但是事务A不论在什么时候查询,看到这行数据的结果都是一致的,事务的一致性

更新逻辑

事务B 的视图 [99,100,101] 并不知道 事务C (102) 的存在 ,是如何 更新出 (1,3)的了

事务B 在更新之前查询一次数据,这个查询值确实是 value = 1

但更新数据的时候,是不能在历史版本更新的更新数据需要先读后写读当前数据(current read)

update 有当前读以外,select 加锁也是当前读
当前读是有锁的,确保一次只有一个事务操作当前版本。

底部

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值