暂无图片
暂无图片
13
暂无图片
暂无图片
暂无图片

OceanBase多版本读一致性

OceanBase 2022-10-03
937

多版本读一致性介绍

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

因此我们需要注意几点:

  • 未提交事务: 不能读到非本事物的未提交事务, 否则若对应事务回滚,就会产生脏读(dirty read)。

  • 事务一致性快照:要读取小于读取版本号的所有提交数据,来保证一个用户可理解的一致性点,否则我们就会产生会返回一半事务(fractured read)。

  • 读写不互斥:在满足未提交事务与事务一致性点的前提下,依旧要保证读写不互斥。

多版本读一致性使用

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

  • 弱一致性读: OceanBase 数据库的弱一致性读依旧提供了事务的一致性快照,不会返回未提交事务和一半事务的情况。

  • 强一致性读:OceanBase 数据库的强一致性读分为两种,分别是事务级别读版本号和语句级别版本号,分别提供给快照读和读已提交两个隔离级别使用,需要提供返回事务一致性点的能力。

  • 只读事务:OceanBase 数据库的只读语句也是要求提供强一致性读相同的能力,需要提供返回事务一致性点的能力。

  • 备份恢复点:OceanBase 数据库需要提供可以备份到一个事务一致性快照,防止备份了多余、未提交的事务或者没有备份需要备份的事务。

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

多版本

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

多版本读一致性实现

事务表

多版本2

事务表是一个内存表,代表本副本中正在执行中的事务集合,事务在执行过程中会根据不同的事务状态,来决定是否要读取到对应的数据。其中数据状态包含提交(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 的关系。

Image

最后修改时间:2022-10-13 11:47:58
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论