MySQL笔记:一致性视图(纯理论)一致性视图

一致性视图

MySQL中,有连个视图的概念:

  • 一个是view,它是用查询语句定义的虚拟表,在调用时执行查询语句,并且生成结果。
  • 另一个是InnoDB在实现MVCC时用到的一致性读视图,用于支持RCRR隔离级别。

1. 事务启动时机

begin/start transaction并不是一个事务的启动时间,只有执行到它们之后第一个操作InnoDB表的语句时,事务才启动。一致性视图是在执行第一个快照读语句时创建。

使用start transaction with consistent snapshot,可以马上启动一个事务。同时创建一个一致性视图。

如果autocommit=1,每个语句就是一个事务,InnoDB隐式执行begincommit

2. 事务ID

InnoDB的每个事务有一个唯一的事务ID,叫transaction id。事务开始时申请,严格递增。

每行数据都有多个版本,每个版本有自己的row trx_id

事务更新数据时,会生成新的数据版本,并且把transaction id赋值给这个版本的事务ID,记为row trx_id

3. 视图数组

视图数组里保存着,启动了但是还没提交的事务ID。

数组里事务ID最小值称为低水位,系统已经创建过的事务ID最大值称为高水位

视图数组和高水位,组成了当前事务的一致性视图(read-view)

数据版本的可见性,是基于数据的row trx_id和一致性视图对比得到。

InnoDB利用所有数据都有多个版本的特性,实现了秒级创建快照的能力。

4. 数据可见性

对于某个数据版本的row trx_id

  • 如果等于当前事务的事务ID,当前事务可见
  • 如果小于低水位,当前事务可见
  • 如果大于高水位,当前事务不可见
  • 如果大于低水位不大于高水位,且不在视图数组中,当前事务可见
  • 如果大于低水位不大于高水位,且在视图数组中,不可见

总结就是,对于一个事务视图:

  • 自己的更新总可见
  • 版本未提交,不可见
  • 版本已提交,但是是在视图创建后提交,不可见
  • 版本已提交,而且是在视图创建前提交,可见

5. 更新逻辑

更新数据都是先读后写的,而且只能读当前值,称为当前读。

当前读总是读取已经提交完成的最新版本。

如果select加锁,也是当前读。

lock in share mode加读锁(S锁,共享锁)

for update加写锁(X锁,排他锁)

6. 可重复读和读提交

  • 可重复读,是在事务开启时创建一致性视图
  • 读提交,是在每一个语句执行前算出新的视图