本文主要介绍 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 数据库对外部查询的原子性保障为:
-
OceanBase 数据库在 Pre-Commit 阶段时,协调者会根据参与者的消息,找到最大的
Prepare Version
作为本事务的
Commit Version
。
-
协调者将
Commit Version
记录到 Prepare Log 中。
-
参与者在收到 Pre-Commit 消息后,将本地的
Publish Version
设置为
Commit Version
,然后应答协调者的 Pre-Commit 消息。此时参与者并不会修改自身的状态,仍旧为 Prepare 阶段。
-
此时,如果发生了切主,并且外部查询需要在新的 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 数据库 参考指南》中的 系统配置项 章节。