一致性视图(Read View)是 MVCC(多版本并发控制)中的核心概念,用于实现事务隔离性。
它是一个逻辑概念,让事务在读取数据时看到特定时间点的数据库快照,而不受其他事务并发修改的影响。
一致性视图是数据库在某个时间点上为每个读操作生成的一个快照,它定义了哪些数据版本是可见的,哪些是不可见的。
这个视图是基于事务的隔离级别和数据库的并发控制机制生成的。
在多用户并发访问数据库的场景中,多个事务可能会同时对数据进行读写操作。如果没有适当的机制,可能会出现以下问题:
- 脏读:一个事务读取到另一个事务尚未提交的更新数据。
- 不可重复读:一个事务在两次读取同一数据时,由于其他事务的修改,导致读取结果不一致。
- 幻读:一个事务在执行过程中,发现新插入的数据满足其查询条件,从而导致结果集不一致。
为了解决这些问题,数据库需要提供一种机制,使得事务在读取数据时能够看到一个一致的、符合隔离级别要求的视图。
一致性视图就是为了解决这些问题而设计的。
一致性视图的工作原理
- 版本链:在支持多版本并发控制(MVCC)的数据库中,每个数据项(如表中的行)会维护多个版本。每个版本都有一个版本号(通常是时间戳或事务ID),用于标识其创建的时间。
- 可见性规则:一致性视图通过一系列规则来决定哪些版本的数据对当前事务是可见的。这些规则通常基于事务的隔离级别(如读已提交、可重复读、串行化等)。
- 读已提交(Read Committed):事务只能看到在它开始之前已经提交的版本。
- 可重复读(Repeatable Read):事务只能看到在它开始之前已经提交的版本,并且在事务执行期间,其他事务对数据的修改不会影响当前事务的视图。
- 串行化(Serializable):事务看到的视图完全独立于其他事务,就像它是串行执行的一样。
一致性视图的优点
- 提高并发性:通过允许多个事务同时读取数据,而不需要等待其他事务完成,从而提高了系统的并发性能。
- 减少锁竞争:在读操作中,一致性视图避免了对数据行的锁竞争,因为读操作可以基于版本链直接获取数据,而不需要锁定数据行。
- 保证一致性:根据隔离级别,一致性视图能够为每个事务提供一个符合其隔离要求的视图,从而保证了数据的一致性。
核心作用
在可重复读(RR)和读已提交(RC)隔离级别下,Read View 确保:
- 可重复读:事务内多次读取同一数据的结果一致。
- 读已提交:只能读取其他事务已提交的数据。
Read View 的结构
Read View 包含三个关键属性:
- trx_ids:生成 Read View 时当前活跃的事务 ID 列表(未提交的事务),可以理解为事务流,由小到大,如同河流的流向。
- low_limit_id:当前最大事务 ID + 1(未来事务的起始 ID)。可以理解为下游事务 ID。
- up_limit_id:trx_ids 中的最小事务 ID。可以理解为上游事务 ID。
一致性视图的创建
当一个事务执行读操作时,数据库会根据当前事务的隔离级别和事务ID,生成一个一致性视图。
这个视图会记录以下信息:
- 创建视图时的最小活跃事务ID:表示在视图创建时,尚未提交的最小事务ID。
- 创建视图时的活跃事务列表:记录在视图创建时,所有尚未提交的事务ID。
版本可见性规则
在读取数据时,一致性视图会根据以下规则判断数据版本是否可见:
如果数据版本的创建事务ID小于视图的最小活跃事务ID,则该版本是可见的(因为创建它的事务已经提交)。
如果数据版本的创建事务ID在视图的活跃事务列表中,则该版本是不可见的(因为创建它的事务尚未提交)。
如果数据版本的创建事务ID大于视图的最小活跃事务ID,则该版本是不可见的(因为创建它的事务尚未开始或尚未提交)。
数据版本的 DB_TRX_ID < up_limit_id : 该事务在 Read View 生成前已提交,数据可见。
- 数据版本的 DB_TRX_ID
∈
trx_ids :该事务在 Read View 生成时未提交,数据不可见。
- 数据版本的 DB_TRX_ID ≥ low_limit_id : 该事务在 Read View 生成后才启动,数据不可见。
- 其他情况 :数据可见(通常是其他事务已提交)。
不同隔离级别下的 Read View
- 可重复读(RR)
事务启动时创建一个固定的 Read View,整个事务期间都使用它。 - 读已提交(RC)
每个语句执行前都会创建新的 Read View,因此能看到其他事务最新提交的数据。
示例说明
假设有以下事务序列:
- 事务 T1(ID=100)启动并查询数据。
- 事务 T2(ID=101)插入一行数据后提交。
- 事务 T3(ID=102)更新 T2 插入的数据。
RR 隔离级别下:
T1 的 Read View 包含 trx_ids=[100]
,up_limit_id=100
,low_limit_id=103
。
- T1 无法看到 T2 插入的数据(DB_TRX_ID=101 ≥ up_limit_id)。
- T1 也无法看到 T3 的更新(DB_TRX_ID=102 ≥ up_limit_id)。
RC 隔离级别下:
T1 每次查询都会生成新的 Read View。
- 第一次查询:看不到 T2 和 T3 的操作。
- 第二次查询:如果 T2 和 T3 已提交,Read View 不包含它们的 ID,因此数据可见。
总结
Read View 通过维护事务启动时的状态,确保事务读取的数据符合隔离级别要求。
它是 MVCC 实现非锁定读的关键机制,让数据库在保证事务隔离性的同时,仍能保持较高的并发性能。
一致性视图是多版本并发控制(MVCC)机制的核心组件,它通过为每个读操作生成一个快照,定义了哪些数据版本是可见的,从而解决了并发环境下的读一致性问题。
它在提高并发性能的同时,也保证了数据的一致性和隔离性。