可重复读隔离级别,事务T启动的时候会创建一个read-view,之后事务T执行期间,即使其他事务修改了数据,事务T看到仍然在启动时看到的一样。也就是说,一个可重复读的隔离级别下执行的事务,好像与世无争,不受影响,那么等到事务自己获取到行锁更新数据的时候,它读到的是什么呢?
begin/start transaction命令并不是一个事务的起点,在执行到它们之后的第一个Innodb语句,事务才真正启动,可以使用start transaction with consistent snapshot这个命令
- 第一种启动方式在执行第一个快照语句的时候创建的。
- 第二种启动方式,一致性视图在执行start transaction with consistent snapnot时创建
- update语句本身就是一个事务
在Mysql里,有两个视图的概念
- 一个是view.它是查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图语法是create view...,而它的查询方法与表一样
- 另一个是Innodb在实现MVCC时用到一致性视图,即consitent read view 用于支持RC和RR隔离级别
快照在MVCC里面是怎样工作的
在可重复读隔离级别下,事务启动的时候就拍了一个快照,这个快照是基于整库的。(那岂不是很慢?)
- Innodb里面每个事务都有一个唯一ID,叫做transactionID,他是在事务开始的时候Innodb的事务系统申请的,严格按照申请顺序严格递增
- 而每行数据也都是有多个版本,每次事务更新数据的时候,都会生成一个新的数据版本,并且吧transaction_id赋值给这个数据版本的事务ID,记为row_trx_id。同时,旧的数据版本也要保留,并且在新的数据版本中,能够有信息可以直接拿到它
undolog
- 图中v1 v2 v3并不是真实存在的,而是每次需要的时候根据当前版本与undo log计算出来的。需要V2的时候,就需要通过v4依次执行U3 U2算出来
- 也就是可重复读隔离级别下,在它启动之后生成的版本号是不认得,他也要找到上一个版本
- 实现上Innodb为每个事务构造了一个数组,用来保存这个事务启动瞬间,当前正在活跃的所有事务ID,活跃指的是启动了但没提交
- 数组里面事务ID最小值记作低水位,当前系统里面创建过的事务ID最大值加1记作高水位
当前事务启动瞬间,一个数据版本的row_trx_id有以下几种可能:
- 如果落在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的
- 如果落在红色部分,这个版本由将来事务自己生成的,这个数据也是可见的。
- 如果落在黄色部分,分为两种情况
a.若row_trx_id在数组中,表示这个版本是由还没提交的事务生成的,不可见
b.若row_trx_id不在数组中,表示这个版本是已经提交了的事务生成的,可见
Innodb利用所有数据都有多个版本的特性,实现了秒级快照能力
更新语句都是先读后写,而这个读,只能是读当前值
标签:事务,极客,快照,隔离,启动,--,Innodb,版本 From: https://www.cnblogs.com/dodogod/p/16709114.html