当前位置 : 主页 > 编程语言 > 其它开发 >

MVCC(多版本并发控制)详解

来源:互联网 收集:自由互联 发布时间:2022-05-30
在 MySQL InnoDB存储引擎下,RC、RR 基于 MVCC 进行并发事务控制, MVCC 是基于“数据版本”对并发事务进行访问 用一个例子来解释一下,下面是一张事务执行流程图: 稍微解释一下: 事务

在 MySQL InnoDB存储引擎下,RC、RR 基于 MVCC 进行并发事务控制, MVCC 是基于“数据版本”对并发事务进行访问
用一个例子来解释一下,下面是一张事务执行流程图:
image.png
稍微解释一下:

  1. 事务 Aid=1088 的记录的 name 改为 “张三”,并提交
  2. 事务 Bid=1088 的记录的 name 改为 “张小三”,并提交
  3. 事务 Cid=1088 的记录的 name 改为 “张老三”,并提交
  4. 事务 D 只是去查询 id=1088 的记录

首先模拟一下在 RC 隔离级别下:事务D 第一次读取的数据是 “张三”,第二次读取的就是“张小三”
这里应该很好理解,因为在 RC 隔离级别下,事务D 能读到 commit 的数据,所以就导致了“不可重复读”问题
如果使用 RR 隔离级别,事务D 的两次读取都是 “张三”
RR 隔离级别是基于 MVCC 实现的,MVCC 又依赖 UNDO_LOGUNDO_LOG就是回滚日志,它是一个版本链,它记录了上一次版本的数据变化
eg:事务 B 把“张三”改为了“张小三”,在UNDO_LOG 中的体现如下:
image.png
注:最原始的数据,也就是最下面这一条,它的 事务ID回滚指针 都是 null
了解了 UNDO_LOG 之后,现在引入一个新的名词:ReadView(快照读)
快照都就是普通的 sql 查询语句:select ....
有了快照读就有当前读,当前读是指:
Insert、Update、Delete、
Select ... for update
Select ... lock in share mode

ReadView 数据结构

image.png
图是从 IT老齐 那儿盗的,稍微解释一下:
m_ids 未提交的事务,不允许读
min_trx_id 就是快要执行完的事务 id
max_trx_id 就是下一个新的事务的 id
creator_trx_id 就是创建这个 ReadView 是哪个事务

RC 原理

RC(读已提交):在每一次执行快照读时生成 ReadView,根据上面的例子
image.png
读了两次,生成了两个 ReadView,先看第一个 ReadView,因为在这个 ReadView 生成的时候,事务1 已经 commit 了,所以他不在活跃事务集合里面,所以 m_ids 是 2,3,4
最小活跃事务就是 2 没有异议
预分配事务id 就是 4+1 = 5
当前的 ReadView 是事务 4 创建的,所以 creator_trx_id = 4
第二个 ReadView 也是一样的的逻辑

版本链数据访问规则:

image.png

RR 原理

可重复读原理很简单,就是复用 ReadView
image.png
eg:在第二次查询的时候,生成的 ReadView 是复用前一次的,所以不会造成 不可重复读

RR 能解决幻读吗?

能,但不完全能。
如果是多次快照读,ReadView会产生复用,没有幻读产生
但是当多次快照读中间存在当前读,ReadView会重新生成,导致产生幻读
image.png

上一篇:6个优秀图片素材网站,全部免费!
下一篇:没有了
网友评论