OceanBase 数据库支持语句级的原子性,语句级的原子性指的是一条语句的操作要么都成功要么都失败,不会存在部分成功部分失败的情况。
当一条语句执行过程中没有报错,那么该语句所做的修改都是成功的,如果一条语句执行过程中报错,那么该语句执行的操作都会被回滚,这种情况称为语句级回滚。语句级回滚有如下特点:
语句回滚时仅回滚本语句的修改,不会影响当前事务该语句之前语句所做的修改。
例如,一个事务有 2 条
UPDATE语句,第一条UPDATE语句执行成功,第二条UPDATE语句执行失败,则只有第二条UPDATE语句会发生语句级回滚,第一条UPDATE语句所做的修改会被保留。语句级回滚的效果等价于语句没有被执行过,即语句执行过程中涉及的全局索引、触发器、行锁等均属于语句的操作,语句回滚需要将这些操作都回滚到语句开启之前的状态。
常见的语句级回滚主要有:
Insert 操作出现主键冲突会导致语句级回滚。
单条语句执行时间过长,语句执行超时可能出现语句级回滚。
多个事务存在行锁冲突导致死锁,某个事务被死锁检测机制 Kill 掉可能会出现语句级回滚。
SQL 语句的语法解析报错不涉及到语句级回滚,因为语句解析报错尚未对数据进行修改。
全局时间戳服务(Global Timestamp Service,简称 GTS),OceanBase 数据库内部每个租户启动一个全局时间戳服务,事务提交时通过本租户的时间戳服务获取事务版本号,保证全局的事务顺序。
服务高可用
GTS 是集群的核心,需要保证高可用。
对于租户而言,OceanBase 数据库使用租户级别 1 号日志流的 Leader 作为 GTS 服务提供者,时间来源于该 Leader 的持久化的可分配区间。GTS 默认是三副本的,其高可用能力跟普通表的能力一样。
GTS Leader通过写下预分配区间日志来申请可分配区间,并依赖日志同步进行副本间信息同步,保证信息不会丢失。
时间戳正确性保证
GTS 维护了全局递增的时间戳服务,异常场景下依然能够保证正确性:
- 新 Leader 上任之前先回放原 Leader 写下的预分配区间日志,获取原可分配区间的最大值,作为自己时间戳授权的基准值。因此该场景下,GTS 提供的时间戳不会回退。
GTS 获取优化
语句快照获取优化
事务提交的时候都会更新其所在机器的 Global Committed Version,当一条语句可以明确其查询所在机器时,如果是一台机器,则直接使用该机器的 Global Committed Version 作为 Read Version,降低对于全局时间戳的请求压力。
事务提交版本号获取优化
多个事务可以合并获取全局时间戳,并且获取时间戳的请求可以提早发送,缩短事务提交时间。




