当前位置: 首页 > article >正文

Read View在MVCC是如何工作的?

多版本并发控制(MVCC, Multi-Version Concurrency Control) 是一种数据库技术,用于在高并发环境下提高读取操作的性能,同时确保数据的一致性。MVCC 通过为每个事务提供一个一致的快照视图(即 Read View),使得读取操作不会被写入操作阻塞,从而减少了锁的竞争。Read View 是 MVCC 的核心概念之一,它决定了事务在执行时能够看到哪些版本的数据。

1. MVCC 的基本原理

在 MVCC 中,数据库为每一行数据维护多个版本(称为 行版本数据版本)。每个版本都与一个特定的事务相关联,并且包含以下信息:

  • 创建该版本的事务 ID:表示哪个事务创建了这个版本。
  • 删除该版本的事务 ID:表示哪个事务删除了这个版本(如果有的话)。

当一个事务读取某一行数据时,它会根据自己的 Read View 来决定应该读取哪个版本的数据。Read View 包含了事务开始时的某些元数据,这些元数据帮助事务判断哪些版本是可见的,哪些版本是不可见的。

2. Read View 的定义

Read View 是一个事务在开始时创建的快照视图,它记录了以下信息:

  • 创建 Read View 时的活跃事务列表:这是在 Read View 创建时,所有尚未提交的事务的列表。这些事务可能正在修改数据,因此它们的修改对当前事务是不可见的。
  • 最小和最大事务 IDRead View 记录了在创建时的最小和最大事务 ID。这有助于快速判断某个事务是否在 Read View 创建之前或之后开始。
  • 创建 Read View 的事务 ID:这是创建 Read View 的事务本身的 ID。当前事务不能看到自己未提交的修改。

3. 如何确定数据版本的可见性

当一个事务读取某一行数据时,它会根据 Read View 来判断该行的各个版本是否对其可见。具体来说,事务会检查以下几个条件:

3.1. 版本的创建事务 ID 小于 Read View 的最小事务 ID

如果某个版本的创建事务 ID 小于 Read View 的最小事务 ID,那么这个版本是在 Read View 创建之前创建的,因此它是可见的。

3.2. 版本的创建事务 ID 在 Read View 的最小和最大事务 ID 之间,但不在活跃事务列表中

如果某个版本的创建事务 ID 在 Read View 的最小和最大事务 ID 之间,但创建该版本的事务不在 Read View 的活跃事务列表中,那么这个版本是可见的。这意味着创建该版本的事务已经提交,因此它的修改是可见的。

3.3. 版本的创建事务 ID 大于 Read View 的最大事务 ID

如果某个版本的创建事务 ID 大于 Read View 的最大事务 ID,那么这个版本是在 Read View 创建之后创建的,因此它是不可见的。

3.4. 版本的删除事务 ID 小于 Read View 的最小事务 ID

如果某个版本的删除事务 ID 小于 Read View 的最小事务 ID,那么这个版本是在 Read View 创建之前被删除的,因此它是不可见的。

3.5. 版本的删除事务 ID 在 Read View 的最小和最大事务 ID 之间,但不在活跃事务列表中

如果某个版本的删除事务 ID 在 Read View 的最小和最大事务 ID 之间,但删除该版本的事务不在 Read View 的活跃事务列表中,那么这个版本是不可见的。这意味着删除该版本的事务已经提交,因此它的删除是有效的。

3.6. 版本的删除事务 ID 大于 Read View 的最大事务 ID

如果某个版本的删除事务 ID 大于 Read View 的最大事务 ID,那么这个版本是在 Read View 创建之后被删除的,因此它是可见的。

4. Read View 的创建时机

Read View 的创建时机取决于数据库的隔离级别和实现方式。以下是几种常见的隔离级别及其对应的 Read View 创建时机:

4.1. READ COMMITTED 隔离级别

READ COMMITTED 隔离级别下,每次读取操作都会创建一个新的 Read View。这意味着每次读取操作只能看到在读取操作开始之前已经提交的事务所做的修改。这种隔离级别允许不可重复读,因为同一事务中的多次读取可能会看到不同的结果。

4.2. REPEATABLE READ 隔离级别

REPEATABLE READ 隔离级别下,事务在第一次读取操作时创建 Read View,并且在整个事务的生命周期内使用同一个 Read View。这意味着事务内的所有读取操作都将看到相同的数据版本,即使其他事务在这期间提交了修改。这种隔离级别防止了不可重复读,但仍然允许幻读(即同一查询范围内的数据集可能会发生变化)。

4.3. SERIALIZABLE 隔离级别

SERIALIZABLE 隔离级别下,除了使用 Read View 来防止脏读和不可重复读之外,还会对查询范围进行锁定,以防止幻读。这意味着事务不仅可以看到一致的数据版本,还可以确保查询范围内的数据不会被其他事务插入或删除。这种隔离级别提供了最高的数据一致性,但也可能导致更多的锁竞争和性能开销。

5. Read View 的工作流程示例

为了更好地理解 Read View 的工作流程,我们可以通过一个具体的例子来说明。

假设有一个表 employees,包含以下数据:

idnamedepartmentcreated_bydeleted_by
1AliceHR10NULL
2BobFinance20NULL
3CharlieIT3040

现在有三个事务:

  • 事务 A:ID 为 10,插入了一条记录 id = 1
  • 事务 B:ID 为 20,插入了一条记录 id = 2
  • 事务 C:ID 为 30,插入了一条记录 id = 3,并在稍后将其删除(deleted_by = 40)。
  • 事务 D:ID 为 50,开始读取数据。
5.1. 事务 D 的 Read View

事务 D 在开始时创建了一个 Read View,假设此时活跃的事务列表为空(即没有其他未提交的事务)。Read View 的内容如下:

  • 最小事务 ID:10(事务 A 的 ID)
  • 最大事务 ID:30(事务 C 的 ID)
  • 活跃事务列表:空
5.2. 事务 D 读取数据

事务 D 读取 employees 表中的数据时,它会根据 Read View 来判断每个版本的可见性:

  • id = 1

    • 创建事务 ID:10
    • 删除事务 ID:NULL
    • 可见性:创建事务 ID 10 小于 Read View 的最大事务 ID 30,且不在活跃事务列表中,因此该版本是可见的。
  • id = 2

    • 创建事务 ID:20
    • 删除事务 ID:NULL
    • 可见性:创建事务 ID 20 小于 Read View 的最大事务 ID 30,且不在活跃事务列表中,因此该版本是可见的。
  • id = 3

    • 创建事务 ID:30
    • 删除事务 ID:40
    • 可见性:创建事务 ID 30 等于 Read View 的最大事务 ID 30,且不在活跃事务列表中,因此该版本是可见的。然而,删除事务 ID 40 大于 Read View 的最大事务 ID 30,因此该版本仍然是可见的。

因此,事务 D 读取到的数据如下:

idnamedepartment
1AliceHR
2BobFinance
3CharlieIT

6. 总结

Read View 是 MVCC 中的关键概念,它为每个事务提供了一个一致的快照视图,确保事务在读取数据时不会被其他事务的写入操作干扰。通过 Read View,事务可以判断哪些数据版本是可见的,哪些是不可见的,从而实现了高效的并发控制。

  • Read View 记录了创建时的活跃事务列表、最小和最大事务 ID,以及创建 Read View 的事务 ID。
  • 事务根据 Read View 来判断数据版本的可见性,确保只读取符合一定条件的版本。
  • 不同隔离级别下的 Read View 创建时机不同,影响了事务的可见性和一致性。

如果你还有任何疑问或需要进一步的帮助,请随时提问!


http://www.kler.cn/a/470977.html

相关文章:

  • unity学习12:地图相关的一些基础2, 增加layer种草种树
  • 数据治理如何激活企业沉睡数据价值?
  • w~自动驾驶~合集16
  • vue3中el-table实现多表头并表格合并行或列
  • JVM实战—13.OOM的生产案例
  • 数字IC设计高频面试题
  • 解密序列建模:理解 RNN、LSTM 和 Seq2Seq
  • 深度学习GPU服务器推荐:打造高效运算平台
  • js 之图片流式转换及图片处理+createObjectURL+canvas+webgl+buffer
  • LED背光驱动芯片RT9293应用电路
  • 用Python进行RU计算
  • Qt pdf分割成png格式
  • 5.zookeeper可视化工具ZooInspector
  • QT自定义工具条渐变背景颜色一例
  • 基于YOLOV5的车辆跟踪与目标检测
  • 【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
  • 【FlutterDart】 listView例子一(13 /100)
  • 高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图
  • 抖音a_bogus,mstoken全参数爬虫逆向补环境2024-06-15最新版
  • 可缩放大屏布局方式
  • K8S中的Pod生命周期之容器探测
  • 理解 maven-jar-plugin:如何使用 Add-Opens 配置解决 Java 模块访问问题
  • 亚远景-ASPICE评估:提升汽车软件开发过程的质量与效率
  • QT中如何通过QFile正确读写、覆盖、追加写入内容?
  • docker的基本操作示例
  • sqli-labs靶场环境搭建