版本链在每次进行 update 或者 delete 操作时,会将每次的操作详细记录在 undo log 中。
每条 undo log 中,都记录了 rol_pointer 信息,通过 roll_pointer 进行关联,可以构成数据的版本链。
一个记录会被一堆事务进行修改,一个记录中就会存在很多 Undo log。
那对某个事务来说,这么多 Undo log,到底应该选择哪些 Undo log 执行回滚呢?
即,哪个版本可以被事务看到呢?
ReadView 机制 就是用来为事务做可见性判断的,它可以判断版本链中的哪个版本是当前事务可见的。
05
ReadView 机制
5.1 什么是 ReadViewReadView(读视图)是多版本并发控制(MVCC)中的一个重要概念。
ReadView 用于控制事务读取数据的逻辑视图,确保事务在整个过程中看到一致的数据状态。
它是如何判断的呢?
ReadView 最重要的 4 个部分:
5.2 ReadView 读取规则用 ReadView 判断哪个版本的数据可读,主要遵循可见性算法。
将要被修改的数据的最新记录中的 DB_TRX_ID(即当前事务 ID)取出来,与系统当前其他活跃事务的 ID 去对比(由Read View维护)。
当被访问版本的 trx_id 属性值:
- 如果 trx_id = creator_trx_ id ,当前事务在访问自己修改过的记录,则该版本可以被当前事务访问。
- 如果 trx_id < min trx_id,表明生成该版本的事务在当前事务生成 ReadView 前已经提交,故该版本可以被当前事务访问。
- 如果 trx_id > = max _trx_id,表明生成该版本的事务在当前事务生成 ReadView 后才开启,故该版本不可以被当前事务访问。
- 如果min_trx_id <= trx _id<= max_trx_id ,那就需要判断一下 trx_id 属性值是不是在 m_ids 列表中,如果在,说明创建 ReadView 时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。
但是,读取已提交 和 可重复读 这两种隔离级别所产生的 ReadViem 是不同的。
- 在读已提交(READ COMMITTED)的隔离级别下:事务中每次对数据进行 SELECT ,都会生成一个 ReadView。
- 在可重复读( REPEATABLE READ)的隔离级别下:在一个事务中对一行数据第一次进行 SELECT 查询,会生成一个 ReadView,之后事务都将使用该 ReadView 进行数据的读取。