OceanBase 数据库两阶段提交过程中未决事务的处理

本文主要介绍 OceanBase 数据库的一阶段提交优化与两阶段提交过程中未决事务的处理。

适用版本

OceanBase 数据库所有版本

一阶段提交优化

与传统数据库不同,OceanBase 数据库的一阶段提交优化是指所有参与者都 Prepare 成功之后,在尚未进入 Commit 的阶段即可让事务推进到结束,返回给客户端

commit OK

的信息,减少提交延时。

OceanBase 数据库采用了多日志流的 Batch Commit,将所有参与者的 Prepare Log 进行 Batch Commit 一同发送给 Follower 副本,从而实现了所有参与者共享日志流。但两阶段提交的流程中,OceanBase 数据库会在参与者向协调者发送

Pre-Commit OK

后向客户端返回

Commit OK

OceanBase 数据库两阶段提交的流程如下图所示:

未决事务的处理方式

参与者会在 Prepare Log 中记录该事务所有参与者的

logid

timestamp

信息,如果参与者在 Commit 阶段提交失败,则参与者可以通过对应的

logid

timestamp

查询 Clog 日志,确认自身是否 Prepare 成功。

对于参与者提交失败的信息,由于会在 Prepare Log 中全局记录,因此 OceanBase 数据库会在失败后重试,因此失败的事务依然可以推进到 Commit 阶段。

在这个过程中,OceanBase 数据库对外部查询的原子性保障为:

  1. OceanBase 数据库在 Pre-Commit 阶段时,协调者会根据参与者的消息,找到最大的

    Prepare Version

    作为本事务的

    Commit Version

  2. 协调者将

    Commit Version

    记录到 Prepare Log 中。

  3. 参与者在收到 Pre-Commit 消息后,将本地的

    Publish Version

    设置为

    Commit Version

    ,然后应答协调者的 Pre-Commit 消息。此时参与者并不会修改自身的状态,仍旧为 Prepare 阶段。

  4. 此时,如果发生了切主,并且外部查询需要在新的 Leader 节点查询该数据,则在访问时会发现该分区处于 Prepare 状态,直到该分区推进到 Clear 后才可以访问。

一阶段提交优化的补充说明

系统配置项

enable_one_phase_commit

用于控制是否开启一阶段提交优化,对于 OceanBase 数据库 V2.2.76 前的版本,该配置项默认为 TRUE,表示开启一阶段提交优化;对于 OceanBase 数据库 V2.2.76 及后续版本,该配置项默认为 FALSE,表示不开启一阶段提交优化。

一阶段提交优化仅适用于单机事务,开启后,事务仅有一个阶段,在所有参与者都写完 Prepare Log 后,协调者就会将

Commit OK

返回给客户端,并将 Clear Request 发送给参与者,不会写入日志。

由于一阶段提交的事务的主备状态是不完全同步的,因此日志文件的回收会依赖全局时间戳,可能会导致某分区 Leader 事务推进异常升级为 Clog 回收失败。如果遇到该问题,可以将

enable_one_phase_commit

设置为 FALSE,可以立即解决该依赖。

关于以上配置项的详细信息,请参见《OceanBase 数据库 参考指南》中的 系统配置项 章节。