---
title: "多版本读一致性 | OceanBase 文档中心"
description: 多版本读一致性 多版本读一致性介绍 为了支持数据读写不互斥, OceanBase 数据库存储了多个版本的数据。为了处理多版本数据的语义，我们需要维护多版本一致性。OceanBase 数据库的多版本一致性是通过读版本和数据版本来保证的，通过给读取版本号，返回小于读取版本号的所有提交数据，来定义多版本一致性。 因此我们需…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 3.2.3 企业版 LTS

# 多版本读一致性

更新时间：2024-08-02 09:57:24

## 多版本读一致性介绍

为了支持数据读写不互斥, OceanBase 数据库存储了多个版本的数据。为了处理多版本数据的语义，我们需要维护多版本一致性。OceanBase 数据库的多版本一致性是通过读版本和数据版本来保证的，通过给读取版本号，返回小于读取版本号的所有提交数据，来定义多版本一致性。

因此我们需要注意几点:

- 未提交事务: 不能读到非本事务的未提交数据, 否则若对应事务回滚，就会产生脏读（dirty read）。
 - 事务一致性快照：要读取小于读取版本号的所有提交数据，来保证一个用户可理解的一致性点，否则我们就会产生会返回一半事务（fractured read）。
 - 读写不互斥：在满足未提交事务与事务一致性点的前提下，依旧要保证读写不互斥。

## 多版本读一致性使用

多版本读一致性在数据库内部是广泛使用的，也是实现并发控制的关键之一：

- 弱一致性读: OceanBase 数据库的弱一致性读依旧提供了事务的一致性快照，不会返回未提交事务和一半事务的情况。
 - 强一致性读：OceanBase 数据库的强一致性读分为两种，分别是事务级别读版本号和语句级别版本号，分别提供给快照读和读已提交两个隔离级别使用，需要提供返回事务一致性点的能力。
 - 只读事务：OceanBase 数据库的只读语句也是要求提供强一致性读相同的能力，需要提供返回事务一致性点的能力。
 - 备份恢复点：OceanBase 数据库需要提供可以备份到一个事务一致性快照，防止备份了多余、未提交的事务或者没有备份需要备份的事务。

用户在使用多版本的过程中，如下图所示：

![多版本](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/6963623461/p358773.jpg)

如上图左所示，数据 A 包含 100 版本已经提交的数据 a，其对应的事务为事务 10 以及已经提交的数据 b，其对应的事务为事务 7；数据 B 包含未决定版本的数据 j 以及对应事务 12 以及已经提交的数据 b，其对应的事务为事务 10；数据 C 包含未决定版本的数据 x 以及对应事务 15 以及已经提交的数据 y，其对应的事务为事务 10。

## 多版本读一致性实现

### 事务表

![多版本2](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/3855765461/p358783.jpg)

事务表是一个内存表，代表本副本中正在执行中的事务集合，事务在执行过程中会根据不同的事务状态，来决定是否要读取到对应的数据。其中数据状态包含提交（COMMIT）、执行（RUNNING）、回滚（ABORT）。对于执行（RUNNING）的事务，可能存在 `本地提交版本号`（local commit version，即 prepare version）；对于提交的事务, 存在 `全局提交版本号`（global commit version，即 commit version）。其中 `全局提交版本号` 代表事务最终的版本，也是我们一致性位点的决定因素。

如上图右所示，事务 6 处于回滚状态；事务 7 处于提交状态，`全局提交版本号` 为 80；事务 12 处于执行状态，不存在 `本地提交版本号`；事务 15 处于执行状态，`本地提交版本号` 为 130。

### 读请求处理

在读取的时候，我们会使用读版本号来读取对应的数据。

接下来我们分开来分析，当读取到提交或回滚的事务时，可以根据 `全局提交时间戳` 和状态比较简单地推测出是否需要读到对应数据。如下图所示，读取请求 r1 以 90 作为读版本号进行读取，根据快照读的策略，会选择版本号为 80，数据为 b 的数据进行读取。

当读取到 RUNNING 状态的事务时，可以安全地跳过这个数据。如下图所示，读取请求 r2 以 130 作为读版本号进行读取，可以安全跳过未进入两阶段提交的事务 12 读取到版本号为 100，数据为 b 的数据。

当读取到 PREPARE 状态的事务时，无法确定事务是否会提交, 因此会等在这行的事务上。如下图所示，读取请求 r3 以 140 作为读版本号进行读取，等待两阶段提交状态且`本地提交时间戳`为 130 的时候最后决定 `全局提交时间戳` 和读时间戳 140 的关系。

![多版本3](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/6963623461/p358802.jpg)

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
