Mysql之MVCC
2021-03-18 11:18
686 查看
InnoDB 里面每个事务有一个唯一的事务 ID,叫作 transaction id。它是在事务开始的时候向 InnoDB 的事务系统申请的,是按申请顺序严格递增的。
每行数据有多个版本,每次事务更新数据的时候,都会生成一个新的数据版本,并且把 transaction id 赋值给这个数据版本的事务 ID,记为 row trx_id。同时,旧的数据版本要保留,并且在新的数据版本中,可以直接拿到它。
上图中三个虚线箭头,即U1、U2、U3就是 undo log,而V1、V2、V3 并不是物理上真实存在的,而是每次需要的时候根据当前版本和 undo log 计算出来的
快照是基于整库的,如何构建的?
按照可重复读的定义,一个事务启动的时候,能够看到所有已经提交的事务结果,但是之后的事务执行期间,其他事务的更新对它不可见。
在实现上, InnoDB 为每个事务构造了一个数组,用来保存这个事务启动瞬间,当前正在“活跃”的所有事务 ID,即启动了但还没提交的事务ID,对应上图中黄色部分。这个数组对应两个概念:
- 低水位:数组里面事务ID最小值
- 高水位:当前系统里面已经创建过的事务 ID 的最大值加 1 记为高水位
由视图数组和高水位,组成了当前事务的一致性视图(read-view),而数据版本的可见性规则,就是基于数据的 row trx_id 和这个一致性视图的对比结果得到的,如下所示:
- 如果落在绿色部分,即小于低水位,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的;
- 如果落在红色部分,即大于等于高水位,表示这个版本是由将来启动的事务生成的,是肯定不可见的;
- 如果落在黄色部分,那就包括两种情况: 若 row trx_id 在数组中,表示这个版本是由还没提交的事务生成的,不可见
- 若 row trx_id 不在数组中,表示这个版本是已经提交了的事务生成的,可见
-- 假设存在事务T1,T2,T4,T7,T8,T9,其中T2,T4,T8活跃状态,此刻启动事务A -- 事务A的视图数组viewA如下 viewA = [T2,T4,T8] -- 低水位 lowLevel = T2 -- 高水位 highLevel = T9 + 1 -- T1:T1 < T2,即处于绿色部分,对于事务A可见 -- T11:T11 > T10,即处于红色部分,对于事务A不可见 -- T4:T4 > T2 && T4 < T10,即处于黄色部分,且存在viewA中,说明未提交不可见 -- T7:T7 > T2 && T7 < T10,即处于黄色部分,但不存在viewA中,说明已提交可见
MVCC只在读已提交和可重复读两个隔离级别下工作,两者的差异在于:
- 读已提交每次读取都会创建一个新的read-view
- 可重复读在同一个事务中共享同一个read-view
相关文章推荐
- mysql Innodb和mvcc
- Mysql中的MVCC
- 轻松理解MYSQL MVCC 实现机制
- MYSQL MVCC实现及其机制(转)
- 【MySQL】MVCC(多版本并发控制)
- MySQL 多版本并发控制(MVCC)
- 关于MySQL如何使用MVCC(多版本控制)来保证在并发的情况下数据的一致性
- MySQL-2 :MVCC及实现介绍
- MySQL InnoDB引擎 MVCC并发控制
- MySQL的并发控制与加锁分析(MVCC/LBCC)
- MySQL引擎、锁以及MVCC关系梳理
- Mysql Innodb中undo-log和MVCC多版本一致性读的实现(源码分析)
- MySQL MVCC实现及其机制
- MySql --MVCC实现原理(乐观锁实现原理)
- MySQL-MVCC并发问题详述
- mysql Multiversion Concurrency Control机制(mvcc)
- MySQL InnoDB MVCC
- mysql-mvcc知识点总结
- 高性能MySQL -MySQL架构,MVCC多版本并发控制和一些基本概念
- java架构之路-(mysql底层原理)Mysql事务隔离与MVCC