高可用方案
=====

OceanBase 数据库提供高可用能力，提升系统的可靠性。OceanBase 数据库的高可用在设计时主要考虑两个方面：

* 当 OceanBase 数据库的节点发生宕机或意外中断等故障时，能够自动恢复数据库的可用性，减少业务受影响时间，避免业务因为数据库节点故障而中断。
* 在 OceanBase 数据库少数节点发生故障导致这部分节点的数据无法读取时，保证业务数据不会丢失。

不同于传统数据库的主备或一主多从方案，OceanBase 数据库使用性价比较高、可靠性略低的服务器，同一数据保存在多台（\>= 3）服务器中的半数以上服务器上（例如 3 台中的 2 台，5 台中的 3 台等），每一笔写事务必须到达半数以上服务器才生效，因此当少数服务器故障时不会有任何数据丢失。

![图片 1.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/1317076061/p184503.png "图片 1.png")

不仅如此，传统数据库主备镜像在主库发生故障时，通常需要外部工具或人工把备库升级成主库，而 OceanBase 数据库底层实现了 Paxos 高可用协议，在主库故障后，剩余的服务器会很快自动选举出新的主库，并继续提供服务。

分布式选举 
--------------

OceanBase 数据库以分区为单位组建 Paxos 协议组。每个分区都有多份副本，通过维护成员组关系，自动建立 Paxos 组。同时在以分区为单位的 Paxos 协议组的基础上，自动选举主副本。

Paxos 协议组中的每个副本在正常工作时分为两种不同的角色：

* **Leader：** 表示主副本，数据库服务的强一致性读以及写服务均是由 Leader 提供的，在此基础上提供分布式事务等多方面的能力。
* **Follower：** 表示从副本，为 Leader 同步的数据进行投票，并提供弱一致性读服务。

分布式选举协议通过 Leader 周期性下发的 Lease 机制来维护自身角色的权威性。在系统出现故障（既包括 Leader 副本所在的机器故障，也包括 Leader 与多数派之间出现网络故障）时，Leader 和 Follower 上记录的 Lease 均会过期。过期后，所有联通的 Follower 副本会自行选举一个新的 Leader 提供读写服务。

分布式选举协议支持对 Leader 角色进行切换。切换 Leader 的操作既可以是总控节点（RootService）发起，也可以由用户通过 alter system 命令发起。

选举协议支持丰富的选举优先级，无主选举和 Leader 切换时考虑的选举优先级如下：

1. 成员组的版本号。
2. 所在副本同步日志的完整程度。
3. locality 中设置的 primary region 信息。
4. 所在副本的一些基础情况（如是否被判定磁盘故障等）。

多副本日志同步 
----------------

Paxos 组成员通过 Redo Log 的多数派强同步来确保数据的持久化。

当一个分区的 Leader 有日志需要提交时，会首先将待提交日志拷贝到本机内存的 Buffer 之中，同时将这部分日志异步的发给多个 Follower。

拷贝到本机 Buffer 的日志会由后台的写盘线程完成落盘操作，并在此之后标记落盘完成。同步给 Follower 的日志会在落盘完成后，给 Leader 回复确认消息。

Leader 只需要收到包括自己在内的多数派的落盘完成消息后，即认为此日志已经完成了强同步，而无需等待其他 Follower 副本的反馈，此时即会向上层返回提交成功。

如果有 Follower 副本出现故障导致缺失了部分日志，这个 Follower 会在故障恢复后，自动从 Leader 副本上补齐所缺失的日志，整个流程是完全自动的。

整个日志提交流程仅需要多数派在线。

多日志流系统 
---------------

如上所述，每个分区是一个独立的 Paxos 组，每个 Paxos 组是一个独立的日志流。

在一个 Paxos 组内部，每个 Paxos 实例对应于一条日志，每条日志在组内有一个唯一的编号，称作 LogID，每个组内的 LogID 均从 1 开始编号，这样的一组日志构成了一个日志流。

每个 observer 进程服务于多个分区，多个分区一同构成了一个多日志流系统。

为了减少磁盘写入的开销，多个日志流会写到相同的日志文件之中。

节点故障的处理策略 
------------------

一台 observer 出现节点故障后，系统会根据参数 server_permanent_offline_time（默认值 3600s）设置的值来进行相应的操作。

如果故障时间小于该参数设置的值，由于节点故障时间较短，认为此进程有可能较快恢复，因此 OceanBase 数据库暂时不做处理，以避免频繁的数据迁移。

如果故障时间大于等于该参数设置的值，OceanBase 数据库会将此机器标记为永久下线。此时会为故障节点上所保存的所有分区进行补副本操作。所补副本仍满足对应租户的 locality 约束。
