【mysql 】 mvcc(多版本并发控制)原理的理解

前言:

大家都知道mysql有四大特性,原子性,一致性,隔离性,持久性,其中隔离性又有四个级别,分别是读未提交,读已提交(RC),可重复读(RR),串行化,然后mysql 的隔离性是如何解决掉的呢,带着疑问,大家一起来找答案。

1、什么是MVCC

在mysql InnoDB 存储引擎下,RC、RR是基于MVCC进行并发事务控制的,MVCC 是基于“数据版本”对并发事务进行访问。

2、实例展现

在这里插入图片描述
RR(可重复读):Select1=张三 Select2=张三
RC(读已提交):Select1=张三 Select2=张小三 可见RC出现了不可重复读

那么RR是怎么保证可重复读的呢,下面说。

3、MVCC基于UNDO_LOG(回滚日志) 版本链

undo_log 版本链的数据不在引用后才会被删除,不用担心数据丢失问题
以上四个事务会有如下的版本链,通过链的方式保存数据的版本变化
在这里插入图片描述
可以看到多出两个字段:TRX_ID(事务ID) 和DB_ROLL_PTR(指针,指向上一个版本变化的数据)

4、ReadView

4.1 什么是快照读 什么是当前读

快照读就是最普通的Select查询sql语句
当前读 指代码执行下面语句时进行读取的方式
Insert、Update、Delete、Select…for update(有锁)、Select…lock in share mode(锁),会通过行锁和间隙锁来实现。

4.2 什么是ReadView

ReadView 是"快照读"SQL执行时 MVCC 提取数据的依据
在快照读的时候才会使用到MVCC

ReadView 是一个数据结构,包含四个字段:
m_ids:当前活跃的事务编号集合。
min_trx_id:最小活跃事务编号。
max_trx_id:预分配事务编号,当前最大事务编号+1。
creator_trx_id:创建者的事务编号

在RC级别下,每次快照读都会生成ReadView

4.3 实例解析读已提交(RC)

如下图,在进行第一个select查询的时候,对应一个ReadView
在这里插入图片描述
如下是一个普通查询在MVCC下查找数据的过程,我们先看RC级别下是如何处理的

4.3.1 第一次查询

在这里插入图片描述
在这里插入图片描述

4.3.2 第二次查询

在这里插入图片描述
在这里插入图片描述

还是按照上面的流程,执行到事务id=2的时候,发现2<min_trx_id=3 成立,说明事务已经提交,此时读到的数据就是张小三

这就是在RC过程的结果,第一次查询张三,第二次张小三,不可重复读

4.4 实例解析可重复读(RR)

可重复读,仅在第一次执行快照读时生成ReadView,后续快照读复用
在这里插入图片描述
因为ReadView进行了复用,并且原始的版本链也没有变化,两次的数据读取的肯定是一样的,都是张三

4.5 RR级别下使用MVCC能避免幻读吗

能,但不完全能,MVCC不是通过锁的方式去让事务完全的隔离,当连续多次快照读,ReadView会产生复用,没有幻读问题,但是当两次快照读之间存在当前读,ReadView会重新生成,导致产生幻读

幻读:同一个事务中,同一条sql第一次查询到的数据,和第二次查询不一致,多了数据或者少了数据,称为幻读

在这里插入图片描述

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值