OceanBase节点操作

隔离节点

当节点发生异常或者需要运维变更时,可以隔离节点。隔离后,新的读写请求不会路由到该节点上,从而可以隔离故障或者无损的执行运维变更动作。

  • 故障隔离场景:节点发生异常时,需要将异常节点与业务流量隔离开来。例如,某机房内有交换机异常,此时某些节点出现丢包、重传,甚至无主选举。为了快速恢复,可以直接隔离这些异常节点。节点恢复后执行 Start 操作恢复节点流量。

  • 运维变更场景:节点需要运维变更时,需要保证对业务流量的透明无感。例如,某节点服务器需要重启时,为了保证重启过程中不影响业务流量,可以执行节点隔离动作,从而将待重启服务器上的业务流量切到其他节点。重启动作完成后执行 Start 操作恢复节点流量。

隔离节点,只是将业务流量从该节点切走,并没有改变 Paxos 投票成员的数量。不同的隔离命令有不同的安全级别保证,需要根据执行的具体的隔离命令仔细斟酌后续能够安全执行的动作。隔离命令适用于短时间隔离的场景,需要持续保持关注,提前做好二次故障的应急预案。如果短时间内恢复不了,可以采用替换节点的方式彻底去除隐患,替换节点的详细操作请参见 替换节点

隔离节点有以下三种命令,不同的隔离命令有不同的安全级别保证:

  • 通过 STOP SERVER 命令隔离节点

  • 通过 FORCE STOP SERVER 命令隔离节点

  • 通过 ISOLATE SERVER 命令隔离节点

使用上述命令成功隔离节点后,被隔离节点的 STATUS 字段仍为 ACTIVE 不变,但 STOP_TIME 字段的值由 NULL 变为隔离操作的时间点,表示该节点处于 Stopped 状态。

STOP SERVER

命令格式如下,一次支持 Stop 多台 server。

obclient [(none)]> ALTER SYSTEM STOP SERVER 'svr_ip1:svr_port1', 'svr_ip2:svr_port2', ...;

STOP SERVER 是最安全的隔离命令。STOP SERVER 不但可以将业务流量从该节点上切走,实现该节点与业务流量隔离的效果,还能保证除被隔离节点以外的其他节点依然能够构成 Paxos 多数派,从而可以安全的对被隔离节点执行任何动作,例如 pstack、调整日志级别等,甚至停止进程。STOP SERVER 适用于需要故障隔离和停机运维的场景,是故障隔离和运维变更首选的隔离命令。

为了保证成功执行后可以安全的对被隔离节点执行任何动作,STOP SERVER 命令前置检测比较严格,通过内部各种状态检查,保证目标节点即使停止进程后,集群剩余可用节点的副本仍然能够构成 Paxos 多数派,从而不影响数据库服务的连续性。

STOP SERVER 命令限制如下:

  1. 不允许同时有多个 Zone 的节点被 Stop,如果同时 Stop 了多个 Zone 的节点,或者已经有其他 Zone 的节点被 Stop,则报错 -4660,cannot stop server or stop zone in multiple zones。如果遇到该错误信息,可以通过查询 DBA_OB_SERVERS 和 DBA_OB_ZONES 视图,确认是否存在多个 Zone 的节点被 Stop。

  2. STOP SERVER 命令通过检查所有租户的所有日志流的 Paxos 成员列表,确认除了目标节点和其他非可用节点外,剩余节点上的副本是否依然能够构成 Paxos 多数派。如果不能构成多数派,则不允许执行 Stop Server 操作。

    1. 非可用节点包括:INACTIVEStoppedACTIVE 状态且 stop_time 字段大于 0)及 DELETING 状态的节点。

    2. 为了检查日志流的 Paxos 成员列表,要求所有日志流都有 Leader,如果发现日志流没有 Leader,则报错 -4179,并且展示有问题的日志流信息。

      例如:租户 1001 的 1 号日志流没有 Leader,则报错信息为 Tenant(1001) LS(1) has no leader, stop server not allowed。如果遇到该错误信息,可以通过查询 GV$OB_LOG_STAT 视图确认日志流的 Leader 副本信息,排查 Leader 副本不正常的问题。

    3. 如果租户的 Locality 属性变更命令与 STOP SERVER 命令并发执行,为了防止误判,禁止在 Locality 变更过程中 Stop 节点。

      例如:租户 1001 正在变更 Locality 减少一个副本,日志流的成员列表正在从 A、B、C 变为 A、B,此时如果需要 Stop B 节点,STOP SERVER 命令可能误判 B 节点可以被 Stop,从而与减少副本操作冲突。为了避免误判,STOP SERVER 命令会报错 -4179,并且展示正在变更的租户信息 Tenant(1001) locality is changing, stop server not allowed。如果遇到该错误信息,可以通过查询 DBA_OB_TENANTS 视图,确认是否存在租户 Locality 变更操作。

    4. 在排除了目标节点和其他非可用节点后,如果剩余节点上的副本不能满足多数派,则报错 -4179,并且展示有问题的日志流信息。

      例如:租户 1001 的 1 号日志流在 Stop 节点后不能满足多数派,则报错信息为 Tenant(1001) LS(1) has no enough valid paxos member after stop server, stop server not allowed。如果遇到该错误信息,可以通过查询 GV$OB_LOG_STAT 视图,确认日志流的成员列表和副本信息是否满足多数派。

  3. STOP SERVER 保证成功执行后,还能够对被隔离节点执行任何侵入性动作。即剩余可用节点上的副本在满足多数派的前提下,还要保证剩余可用节点中的多数派副本的日志是同步的,使得被隔离节点即使停止进程后,剩余节点的日志依然能够形成多数派。

    1. 日志同步判断条件:对比日志流的 Follower 副本和 Leader 副本的最新日志位点,日志位点差距在 5 秒以内即认为日志是同步的。可以通过查询 GV$OB_LOG_STAT 视图的 END_SCN 字段,获取指定日志流的各个副本的最新日志位点。

    2. 如果不满足该条件,则报错 -4179,并且展示有问题的日志流信息。

      例如:租户 1001 的 1 号日志流日志不同步,则报错信息为 Tenant(1001) LS(1) log not sync, stop server not allowed。如果遇到该错误信息,可以通过查询 GV$OB_LOG_STAT 视图的 END_SCN 字段确认日志流副本同步情况。

    # 获取指定日志流副本的最新日志位点信息,并转换成时间戳形式
    obclient [(none)]> SELECT SCN_TO_TIMESTAMP(END_SCN) FROM GV$OB_LOG_STAT WHERE TENANT_ID = 1001 and LS_ID = 1;
    

STOP SERVER 是最安全的隔离命令,但同时它的前置条件也是最严格的。在实际应用中,特别是故障应急场景下,可能无法完全满足上述前置条件,进而导致 STOP SERVER 命令无法执行成功。因此 OceanBase 数据库提供了另外两种节点隔离命令,FORCE STOP SERVER 和 ISOLATE SERVER。他们不同程度的放松了前置检查,减少了限制,从而在更多场景下能够成功隔离节点,但节点被隔离后的操作有所限制。任何场景下都应该首选 STOP SERVER 命令,STOP SERVER 无法成功的情况下可以选择弱化版本的节点隔离命令,但弱化版本的节点隔离后能够执行的操作会有所限制。

FORCE STOP SERVER

相比于 STOP SERVER 命令,FORCE STOP SERVER 跳过了日志同步检查。FORCE STOP SERVER 命令能够保证将业务流量从被隔离节点上切走,但不能保证被隔离节点能够安全的停止进程。强行停止进程后可能破坏 Paxos 多数派,从而影响数据库服务的连续性。

FORCE STOP SERVER 的典型应用场景:A、B、C 三个节点,B 节点的副本日志存在较大延迟,例如 1 个小时。此时节点 C 出现硬件异常需要停机运维。为了保证隔离后能够安全的停止进程,我们首选 STOP SERVER 命令隔离节点,但由于 B 节点的副本日志存在较大延迟,STOP SERVER 命令无法执行成功。我们只能退而其次选择 FORCE STOP SERVER 命令来隔离节点,首先避免硬件异常对业务流量造成影响。然后排查 B 节点日志延迟的原因,待 B 节点日志实时后再次尝试执行 STOP SERVER 命令,成功执行后可以安全的进行停机运维。

obclient [(none)]> ALTER SYSTEM FORCE STOP SERVER 'svr_ip1:svr_port1', 'svr_ip2:svr_port2', ...;
警告

FORCE STOP SERVER 仅仅适用于除了待隔离节点外存在其他节点日志延迟的场景,此时隔离节点的目的仅仅是故障隔离,不能进行任何会造成进程停止的侵入性动作。否则会破坏 Paxos 多数派,造成租户无主,影响数据库服务的连续性。

ISOLATE SERVER

相比于 STOP SERVER 和 FORCE STOP SERVERISOLATE SERVER 的前置检查最为宽松,响应速度最快。它不保证安全性,即不保证目标节点下线后,集群剩余节点的副本可以组成 Paxos 多数派继续提供服务。

obclient [(none)]> ALTER SYSTEM ISOLATE SERVER 'svr_ip1:svr_port1', 'svr_ip2:svr_port2', ...;

ISOLATE SERVER 命令前置检查放松逻辑如下:

  1. ISOLATE SERVER 命令不再限制多个 Zone 的节点同时隔离,如果已经有其他 Zone 的节点被隔离(执行任何一种隔离命令),也可以执行 ISOLATE SERVER 命令。

    典型场景:集群有三个 Zone(Z1、Z2、Z3),Z1 和 Z3 各自一个节点出现故障,需要隔离。Z1 故障节点隔离成功后,如果采用 STOP SERVER 或者 FORCE STOP SERVER 命令继续隔离 Z3 故障节点,会报错不允许同时隔离多个 Zone。此时仅能执行 ISOLATE SERVER 命令,将业务流量从故障节点上切走,隔离后不能进行任何会造成进程停止的侵入性动作。

  2. ISOLATE SERVER 命令不再检查日志流副本的多数派和日志同步情况,即使不满足相应条件,也可以执行 ISOLATE SERVER 命令。

    典型场景:日志流初始的 Paxos 成员列表为 A、B、C 三个节点,C 节点机器宕机后永久下线,日志流的成员列表变更为 A、B,处于缺副本状态。此时如果 B 节点发生硬件故障并希望隔离该节点,STOP SERVER 和 FORCE STOP SERVER 均会失败,报错为剩余副本不满足多数派。此时仅能执行 ISOLATE SERVER 命令,将业务流量从故障节点上切走,隔离后不能进行任何会造成进程停止的侵入性动作。

ISOLATE SERVER 命令限制如下:

当出现多个 Zone 节点被隔离时,ISOLATE SERVER 会检查所有租户的 Primary Zone 属性,要求不能同时隔离一个租户 Primary Zone 所在地域的所有 Zone 的节点,以防止租户的读写服务切到其他地域,进而业务请求跨城访问导致耗时大幅增加。

可以通过 DBA_OB_TENANTS 视图检查租户的 Primary Zone 属性,结合 DBA_OB_ZONES 和 DBA_OB_SERVERS 视图中已经隔离的 Zone 和节点的信息,确认是否打破上述限制条件。

警告

ISOLATE SERVER 仅仅适用于除了待隔离节点外存在其他节点状态异常的场景,此时隔离节点的目的仅仅是故障隔离,不能进行任何会造成进程停止的侵入性动作。否则会破坏 Paxos 多数派,造成租户无主,影响数据库服务的连续性。

总结

任何场景下都应该首选 STOP SERVER 命令,成功执行后除了达成故障隔离的目的,还可以保证能够安全的对被隔离节点执行任何应急动作和运维动作。STOP SERVER 无法成功的情况下可以选择弱化版本的节点隔离命令,但弱化版本的节点隔离后不能保证能够安全的执行侵入性动作。

FORCE STOP SERVER 适用于除了待隔离节点外存在其他节点日志延迟的场景,ISOLATE SERVER 适用于除了待隔离节点外存在其他节点状态异常的场景。此时隔离节点的目的仅仅是故障隔离,不能进行任何会造成进程停止的侵入性运维动作,否则会破坏 Paxos 多数派,造成租户无主,影响数据库服务的连续性。

替换节点

替换节点适用于硬件故障场景、容量场景(不同规格机器替换),替换后集群的节点数量不变。替换节点是一套运维操作的组合:即先添加新节点并迁移副本,然后再删除旧节点,整体时间较长。

操作步骤

  1. 使用 root 用户登录到集群的 sys 租户。

    连接示例如下,连接数据库时请以实际环境为准。

    obclient -h10.xx.xx.xx -P2883 -uroot@sys#obdemo -p***** -A
    

    有关更加详细的连接数据库的操作指引,参见 连接数据库概述(MySQL 模式) 和 连接数据库概述(Oracle 模式)

  2. 在待替换节点所在的 Zone 上添加新节点。

    添加新节点的详细操作请参见 添加节点

  3. 将旧节点上的 Unit 迁移到新节点。

    1. 查询 DBA_OB_SERVERS 视图获取待替换节点的相关信息。

      查询示例如下:

      obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_SERVERS;
      +-------------+----------+----+--------------+----------+-----------------+--------+----------------------------+-----------+-----------------------+----------------------------+----------------------------+-------------------------------------------------------------------------------------------+
      | SVR_IP      | SVR_PORT | ID | ZONE         | SQL_PORT | WITH_ROOTSERVER | STATUS | START_SERVICE_TIME         | STOP_TIME | BLOCK_MIGRATE_IN_TIME | CREATE_TIME                | MODIFY_TIME                | BUILD_VERSION                                                                             |
      +-------------+----------+----+--------------+----------+-----------------+--------+----------------------------+-----------+-----------------------+----------------------------+----------------------------+-------------------------------------------------------------------------------------------+
      | 172.xx.xx.xx|     2882 |  6 | sa128_obv4_2 |     2881 | NO              | ACTIVE | 2022-12-30 16:17:03.173519 | NULL      | NULL                  | 2022-12-30 16:08:04.749100 | 2023-01-04 11:48:36.589270 | 4.0.0.0_101000022022120716-0d7927892ad6d830e28437af099f018b0ad9a322(Dec  7 2022 16:22:15) |
      | 172.xx.xx.xx|     2882 |  4 | sa128_obv4_3 |     2881 | NO              | ACTIVE | 2022-12-30 16:36:35.567437 | NULL      | NULL                  | 2022-12-30 16:08:02.755200 | 2023-01-04 14:13:36.976548 | 4.0.0.0_101000022022120716-0d7927892ad6d830e28437af099f018b0ad9a322(Dec  7 2022 16:22:15) |
      | 172.xx.xx.xx|     2882 |  3 | sa128_obv4_3 |     2881 | NO              | ACTIVE | 2022-12-12 12:42:00.054759 | NULL      | NULL                  | 2022-11-03 15:37:09.530894 | 2022-12-22 14:43:26.717736 | 4.0.0.0_101000022022120716-0d7927892ad6d830e28437af099f018b0ad9a322(Dec  7 2022 16:22:15) |
      | 172.xx.xx.xx|     2882 |  1 | sa128_obv4_1 |     2881 | NO              | ACTIVE | 2022-12-12 12:25:17.555651 | NULL      | NULL                  | 2022-11-03 15:37:08.990683 | 2022-12-12 12:25:18.553763 | 4.0.0.0_101000022022120716-0d7927892ad6d830e28437af099f018b0ad9a322(Dec  7 2022 16:22:15) |
      | 172.xx.xx.xx|     2882 |  2 | sa128_obv4_2 |     2881 | YES             | ACTIVE | 2022-12-12 11:46:37.222980 | NULL      | NULL                  | 2022-11-03 15:37:09.490511 | 2022-12-12 11:47:31.075335 | 4.0.0.0_101000022022120716-0d7927892ad6d830e28437af099f018b0ad9a322(Dec  7 2022 16:22:15) |
      | 172.xx.xx.xx|     2882 |  5 | sa128_obv4_1 |     2881 | NO              | ACTIVE | 2022-12-30 16:25:45.420996 | NULL      | NULL                  | 2022-12-30 16:08:03.928478 | 2023-01-04 11:48:36.578231 | 4.0.0.0_101000022022120716-0d7927892ad6d830e28437af099f018b0ad9a322(Dec  7 2022 16:22:15) |
      +-------------+----------+----+--------------+----------+-----------------+--------+----------------------------+-----------+-----------------------+----------------------------+----------------------------+-------------------------------------------------------------------------------------------+
      6 rows in set
      

      有关 DBA_OB_SERVERS 视图的更多详细信息,请参见 DBA_OB_SERVERS

    2. 根据节点 IP 查询待替换的节点的 Unit 列表。

      语句如下:

      obclient [(none)]> SELECT  unit_id FROM  oceanbase.DBA_OB_UNITS WHERE SVR_IP = 'svr_ip';
      

      其中,svr_ip 需要根据实际情况填写待替换节点的 IP 地址。

      查询示例如下:

      obclient [(none)]> SELECT unit_id FROM  oceanbase.DBA_OB_UNITS WHERE SVR_IP = '172.xx.xx.xx';
      +---------+
      | unit_id |
      +---------+
      |       1 |
      |    1002 |
      |    1016 |
      |    1024 |
      +---------+
      4 rows in set
      
    3. 提交 Unit 迁移任务,将旧节点上的 Unit 迁移到同 Zone 的其他节点上。

      语句如下:

      obclient [(none)]> ALTER SYSTEM MIGRATE UNIT unit_id DESTINATION 'svr_ip:svr_port';
      

      相关参数说明如下:

      • unit_id:待迁移的 Unit 的 unit_id。

      • svr_ip:svr_port:新节点的 IP 地址和 RPC 端口号,端口号默认为 2882。

      每条命令仅支持迁移一个 Unit,多个 Unit 需要执行多次该命令。

      迁移示例如下:

      obclient [(none)]> ALTER SYSTEM MIGRATE UNIT 1016 DESTINATION '172.xx.xx.xx:2882';
      
    4. 查询 oceanbase.DBA_OB_UNIT_JOBS 视图,确认 Unit 的迁移进度。

      obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_UNIT_JOBS WHERE JOB_TYPE = 'MIGRATE_UNIT';
      +--------+--------------+------------+-------------+----------+----------------------------+----------------------------+-----------+---------+----------+------------+------------+-------------+
      | JOB_ID | JOB_TYPE     | JOB_STATUS | RESULT_CODE | PROGRESS | START_TIME                 | MODIFY_TIME                | TENANT_ID | UNIT_ID | SQL_TEXT | EXTRA_INFO | RS_SVR_IP  | RS_SVR_PORT |
      +--------+--------------+------------+-------------+----------+----------------------------+----------------------------+-----------+---------+----------+------------+------------+-------------+
      |      4 | MIGRATE_UNIT | INPROGRESS |        NULL |        0 | 2023-01-04 17:22:02.208219 | 2023-01-04 17:22:02.208219 |      1004 |    1006 | NULL     | NULL       |xx.xx.xx.106|        2882 |
      +--------+--------------+------------+-------------+----------+----------------------------+----------------------------+-----------+---------+----------+------------+------------+-------------+
      

      如果查询结果为空,则表示 Unit 迁移完成。

    更多关于 Unit 迁移的操作及说明,请参见 Unit 迁移

  4. 等待旧节点上的所有 Unit 迁移完成后,将旧节点删除。

    具体操作如下:

    1. 执行以下命令,删除旧节点。

      语句如下:

      obclient [(none)]> ALTER SYSTEM DELETE SERVER 'svr_ip:svr_port' [,'svr_ip:svr_port'...] [ZONE [=] 'zone_name']
      

      相关参数说明如下:

      • svr_ip:表示待删除的旧节点的 IP。

      • port:表示待删除的旧节点的 RPC 端口,默认为 2882。

      • zone_name:待删除的旧节点所属的 Zone。

      示例如下:

      obclient [(none)]> ALTER SYSTEM DELETE SERVER "172.xx.xx.xx:2882" zone='zone1'
      
    2. 待操作结束后,查询 oceanbase.DBA_OB_SERVERS 视图,确认旧节点是否删除成功。

      obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_SERVERS;
      

      如果列表中已经查询不到旧节点信息,则表示删除成功。如果列表中仍然有该节点,且该节点的状态为 DELETING,则表示该节点仍然在删除状态中。

启动 Zone

 

启动 Zone 的操作通常用于允许 Zone 内的所有服务器对外提供服务的场景。

背景信息

启动 Zone 通常使用在以下场景:

  • 添加了新的 Zone,且该 Zone 的状态为 INACTIVE,当前需要使用该 Zone 内的服务器。

  • 当前 Zone 因业务原因被隔离,且该 Zone 的状态为 INACTIVE,需要执行启动 Zone 操作使 Zone 解除隔离。

操作步骤

  1. 使用 root 用户登录到集群的 sys 租户。

    连接示例如下,连接数据库时请以实际环境为准。

    obclient -h10.xx.xx.xx -P2883 -uroot@sys#obdemo -p***** -A
    

    有关更加详细的连接数据库的操作指引,参见 连接数据库概述(MySQL 模式) 和 连接数据库概述(Oracle 模式)

  2. 执行以下命令,启动 Zone。

    语句如下:

    obclient [(none)]> ALTER SYSTEM START ZONE zone_name;
    

    其中,zone_name 为待启动的 Zone 的名称。每条语句每次仅支持启动一个 Zone。

    示例如下:

    obclient [(none)]> ALTER SYSTEM START ZONE zone4;
    Query OK, 0 rows affected
    
  3. 操作成功后,可以查询 DBA_OB_ZONES 视图进行确认。

    obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ZONES;
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    | ZONE  | CREATE_TIME                | MODIFY_TIME                | STATUS | IDC | REGION   | TYPE      |
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    | zone1 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.801054 | ACTIVE | HZ0 | hangzhou | ReadWrite |
    | zone2 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.809504 | ACTIVE | HZ0 | hangzhou | ReadWrite |
    | zone3 | 2022-12-20 17:50:17.169804 | 2023-01-30 17:34:11.228474 | ACTIVE | HZ1 | hangzhou | ReadWrite |
    | zone4 | 2023-01-06 15:30:30.887362 | 2023-01-31 13:47:56.107429 | ACTIVE | hz1 | hangzhou | ReadWrite |
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    4 rows in set
    

    根据查询结果可以看到,Zone 的状态从 INACTIVE 变为 ACTIVE,表示 Zone 启动成功。

添加 Zone

添加 Zone 通常用于集群的扩容场景中。

操作步骤

  1. 使用 root 用户登录到集群的 sys 租户。

    连接示例如下,连接数据库时请以实际环境为准。

    obclient -h10.xx.xx.xx -P2883 -uroot@sys#obdemo -p***** -A
    

    有关更加详细的连接数据库的操作指引,参见 连接数据库概述(MySQL 模式) 和 连接数据库概述(Oracle 模式)

  2. 执行以下命令,在集群中添加 Zone。

    语句如下:

    obclient [(none)]> ALTER SYSTEM ADD ZONE zone_name [IDC [=] 'idc_name', REGION [=] 'region_name', ZONE_TYPE [=] 'ReadWrite'];
    

    相关参数说明如下:

    • zone_name:待添加的 Zone 的名称,每条语句每次仅支持添加一个 Zone。如果需要添加多个 Zone,需要重复执行该语句。

    • idc_name:指定 Zone 所在机房的名称。如果不指定,默认为空。

    • region_name:指定 Zone 所在 Region 的名称,如果不指定,默认值为 default_region

    • ZONE_TYPE:指定 Zone 的类型,当前版本仅支持读写 Zone(ReadWrite)。如果不指定,默认为读写 Zone。

    在集群中增加 zone4 的示例如下:

    obclient [(none)]> ALTER SYSTEM ADD ZONE zone4 IDC 'hz1', REGION 'hangzhou';
    
  3. 操作成功后,可以查询 oceanbase.DBA_OB_ZONES 视图进行确认。

    obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ZONES;
    +-------+----------------------------+----------------------------+----------+-----+----------+-----------+
    | ZONE  | CREATE_TIME                | MODIFY_TIME                | STATUS   | IDC | REGION   | TYPE      |
    +-------+----------------------------+----------------------------+----------+-----+----------+-----------+
    | zone1 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.801054 | ACTIVE   | HZ0 | hangzhou | ReadWrite |
    | zone2 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.809504 | ACTIVE   | HZ0 | hangzhou | ReadWrite |
    | zone3 | 2022-12-20 17:50:17.169804 | 2022-12-20 17:50:40.815833 | ACTIVE   | SH0 | shanghai | ReadWrite |
    | zone4 | 2023-01-06 14:57:18.775946 | 2023-01-06 14:57:18.776974 | INACTIVE | hz1 | hangzhou | ReadWrite |
    +-------+----------------------------+----------------------------+----------+-----+----------+-----------+
    4 rows in set
    

    查询结果中有新添加的 Zone,则表示添加 Zone 成功,新添加成功的 Zone 的状态为 INACTIVE

    有关 DBA_OB_ZONES 视图的更多详细信息,请参见 oceanbase.DBA_OB_ZONES

  4. 添加 Zone 后,如果需要使用该 Zone,还需要启动 Zone,使 Zone 的状态变为 ACTIVE

    语句如下:

    obclient [(none)]> ALTER SYSTEM START ZONE zone_name;
    

    其中,zone_name 为待启动的 Zone 的名称。

    示例如下:

    obclient [(none)]> ALTER SYSTEM START ZONE zone4;
    Query OK, 0 rows affected
    
    obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ZONES;
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    | ZONE  | CREATE_TIME                | MODIFY_TIME                | STATUS | IDC | REGION   | TYPE      |
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    | zone1 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.801054 | ACTIVE | HZ0 | hangzhou | ReadWrite |
    | zone2 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.809504 | ACTIVE | HZ0 | hangzhou | ReadWrite |
    | zone3 | 2022-12-20 17:50:17.169804 | 2023-01-30 17:34:11.228474 | ACTIVE | HZ1 | hangzhou | ReadWrite |
    | zone4 | 2023-01-06 15:30:30.887362 | 2023-01-31 13:47:56.107429 | ACTIVE | hz1 | hangzhou | ReadWrite |
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    4 rows in set
    

    根据示例结果可知,成功启动 Zone 后,新添加的 Zone 的状态变为 ACTIVE

删除 Zone

删除 Zone 通常用于集群缩容的场景中。

前提条件

删除 Zone 前,需要确认以下事项:

  • 请确认该 Zone 下已不存在节点,查看 Zone 内节点的相关操作可参见 查看节点

  • 请确认该 Zone 已停止。

    停止 Zone 的语句如下:

    obclient [(none)]> ALTER SYSTEM STOP ZONE zone_name;
    

    其中,zone_name 为待停止的 Zone 的名称。每条语句每次仅支持停止一个 Zone。

    示例如下:

    obclient [(none)]> ALTER SYSTEM STOP ZONE zone4;
    

操作步骤

  1. 使用 root 用户登录到集群的 sys 租户。

    连接示例如下,连接数据库时请以实际环境为准。

    obclient -h10.xx.xx.xx -P2883 -uroot@sys#obdemo -p***** -A
    

    有关更加详细的连接数据库的操作指引,参见 连接数据库概述(MySQL 模式) 和 连接数据库概述(Oracle 模式)

  2. 执行以下命令,删除集群中的 Zone。

    语句如下:

    obclient [(none)]> ALTER SYSTEM DELETE ZONE zone_name;
    

    其中,zone_name 表示待删除的 Zone 的名称。每条语句每次仅支持删除一个 Zone。如果需要删除多个 Zone,则需要重复执行该语句。

    删除集群中的 zone4 的示例如下:

    obclient [(none)]> ALTER SYSTEM DELETE ZONE zone4;
    
  3. 操作成功后,可以查询 oceanbase.DBA_OB_ZONES 视图进行确认。

    obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ZONES;
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    | ZONE  | CREATE_TIME                | MODIFY_TIME                | STATUS | IDC | REGION   | TYPE      |
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    | zone1 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.801054 | ACTIVE | HZ0 | hangzhou | ReadWrite |
    | zone2 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.809504 | ACTIVE | HZ0 | hangzhou | ReadWrite |
    | zone3 | 2022-12-20 17:50:17.169804 | 2022-12-20 17:50:40.815833 | ACTIVE | SH0 | shanghai | ReadWrite |
    +-------+----------------------------+----------------------------+--------+-----+----------+-----------+
    3 rows in set
    

    查询结果中没有该 Zone,则表示删除 Zone 成功。

修改 Zone

修改 Zone 主要修改 Zone 所属的 Region 及 IDC 信息。

使用限制

当前不支持修改 Zone 的 ZONE_TYPE

操作步骤

  1. 使用 root 用户登录到集群的 sys 租户。

    连接示例如下,连接数据库时请以实际环境为准。

    obclient -h10.xx.xx.xx -P2883 -uroot@sys#obdemo -p***** -A
    

    有关更加详细的连接数据库的操作指引,参见 连接数据库概述(MySQL 模式) 和 连接数据库概述(Oracle 模式)

  2. 执行以下命令,修改 Zone 属性。

    语句如下:

    obclient [(none)]> ALTER SYSTEM {ALTER|CHANGE|MODIFY} ZONE zone_name SET [IDC [=]'idc_name', REGION [=]'region_name'];
    

    相关参数说明如下:

    • {ALTER|CHANGE|MODIFY} :表示 ALTERCHANGEMODIFY 三者的功能相同,可以使用任意一个关键字来修改 Zone 属性。

    • zone_name:表示待修改的 Zone 的名称。每条语句每次仅支持修改一个 Zone。

    • idc_name:指定 Zone 所在机房的名称。

    • region_name:指定 Zone 所在 Region 的名称。

    例如,将当前集群所处的区域(Region)修改为 shanghai,所处的机房修改为 sh1 的示例如下:

    obclient [(none)]> ALTER SYSTEM ALTER ZONE zone4 SET REGION 'shanghai',IDC 'sh1';
    
  3. 操作成功后,可以查询 oceanbase.DBA_OB_ZONES 视图进行确认。

    obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ZONES;
    +-------+----------------------------+----------------------------+----------+-----+----------+-----------+
    | ZONE  | CREATE_TIME                | MODIFY_TIME                | STATUS   | IDC | REGION   | TYPE      |
    +-------+----------------------------+----------------------------+----------+-----+----------+-----------+
    | zone1 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.801054 | ACTIVE   | HZ0 | hangzhou | ReadWrite |
    | zone2 | 2022-12-20 17:50:17.168745 | 2022-12-20 17:50:40.809504 | ACTIVE   | HZ0 | hangzhou | ReadWrite |
    | zone3 | 2022-12-20 17:50:17.169804 | 2022-12-20 17:50:40.815833 | ACTIVE   | SH0 | shanghai | ReadWrite |
    | zone4 | 2023-01-06 15:25:07.190559 | 2023-01-06 15:25:29.281242 | INACTIVE | sh1 | shanghai | ReadWrite |
    +-------+----------------------------+----------------------------+----------+-----+----------+-----------+
    4 rows in set

 

隔离 Zone

为了实现 OceanBase 数据库的高级别容灾功能,我们引入了 Zone 的概念。Zone 是一个逻辑概念,一般是具有相似容灾属性的一组节点的组合。从物理层面来讲,一个 Zone 通常是一个独立的物理部署单元,可以是一个数据中心(IDC)或者云上的一个可用区,也可以是一个单独的机架(Rack)。通过将 OceanBase 集群部署于多个 Zone (通常至少 3 个 Zone),实现单个 Zone 故障时的故障隔离及快速恢复。

当需要进行 Zone 级容灾或者 Zone 级运维变更时,可以隔离 Zone。隔离后,新的读写请求不会路由到该 Zone 内的节点上,从而可以隔离故障或者无损的执行运维变更动作。

  • 故障隔离场景:例如多机房部署架构下,某机房内有交换机异常,此时部分节点出现丢包、重传,甚至无主选举。为了快速恢复,可以直接隔离该机房对应的 Zone。

  • 运维变更场景:例如 OceanBase 集群升级时采用的轮转升级方案,首先隔离一个 Zone,将用户流量从该 Zone 切到其他 Zone,然后执行升级动作。该 Zone 升级完成后执行 Start 操作恢复流量,再依次升级其他 Zone,从而做到升级对用户透明。

隔离 Zone,只是将用户流量从该 Zone 切走,并没有改变 Paxos 投票成员的数量。不同的隔离命令有不同的安全级别保证,需要根据执行的具体的隔离命令仔细斟酌后续能够安全执行的动作。隔离命令适用于短时间隔离场景,需要持续保持关注,提前做好二次故障的应急预案。如果短时间内恢复不了,可以采用替换 Zone 的方式彻底去除隐患。

隔离 Zone 有以下三种命令,不同的隔离命令有不同的安全级别保证:

  • 通过 STOP ZONE 命令隔离 Zone

  • 通过 FORCE STOP ZONE 命令隔离 Zone

  • 通过 ISOLATE ZONE 命令隔离 Zone

通过以上命令成功隔离 Zone 后,Zone 的 STATUS 的值变为 INACTIVE,表示该 Zone 处于隔离状态。

STOP ZONE

命令格式如下:

obclient [(none)]> ALTER SYSTEM STOP ZONE 'zone_name';

STOP ZONE 是最安全的隔离命令。STOP Zone 不但可以将业务流量从该 Zone 切走,实现 Zone 内节点与业务流量隔离的效果,还能保证除被隔离 Zone 以外的其他 Zone 的节点依然能够构成 Paxos 多数派,从而可以安全的对被隔离 Zone 的节点执行任何动作,例如 pstack、调整日志级别等,甚至停止进程。STOP ZONE 适用于需要故障隔离和停机运维的场景,是故障隔离和运维变更首选的隔离命令。

为了保证成功执行后可以安全的对被隔离 Zone 内的节点执行任何动作,STOP ZONE 命令前置检测比较严格,通过内部各种状态检查,保证目标节点即使停止进程后,集群剩余可用节点的副本仍然能够构成 Paxos 多数派,从而不影响数据库服务的连续性。

STOP ZONE 命令限制如下:

  1. 不允许同时有多个 Zone 以及多个 Zone 的节点被 Stop,如果已经有其他 Zone 或者其他 Zone 的节点被 Stop,则 STOP ZONE 报错 -4660,cannot stop server or stop zone in multiple zones。如果遇到该错误信息,可以通过查询 DBA_OB_SERVERS 和 DBA_OB_ZONES,确认是否存在 Zone 或者节点被 Stop。

  2. STOP ZONE 命令通过检查所有租户的所有日志流的 Paxos 成员列表,确认除了目标 Zone 节点和其他非可用节点外,剩余节点上的副本是否依然能够构成 Paxos 多数派。如果不能构成多数派,则不允许执行 STOP ZONE 操作。

    1. 非可用节点包括 INACTIVEstoppedACTIVE 状态且 stop_time 字段大于 0)及 DELETING 状态的节点。

    2. 为了检查日志流的 Paxos 成员列表,要求所有日志流都有 Leader,如果发现日志流没有 Leader,则报错 -4179,并且展示有问题的日志流信息。

      例如:租户 1001 的 1 号日志流没有 Leader,则报错信息为 Tenant(1001) LS(1) has no leader, stop zone not allowed。如果遇到该错误信息,可以通过查询 GV$OB_LOG_STAT 视图确认日志流的 Leader 副本信息,排查 Leader 副本不正常的问题。

    3. 如果租户的 Locality 属性变更与 STOP ZONE 命令并发,为了防止误判,禁止在 Locality 变更过程中 STOP ZONE

      例如:租户 1001 正在变更 Locality 减少一个副本,日志流的成员列表正在从 A、B、C 变为 A、B,此时如果需要 Stop B 节点所在的 Zone,STOP ZONE 命令可能误判可以被 Stop,从而与减少副本操作冲突。为了避免误判,STOP ZONE 命令会报错 -4179,并且展示正在变更的租户信息 Tenant(1001) locality is changing, stop zone not allowed。如果遇到该错误信息,可以通过查询 DBA_OB_TENANTS 视图,确认是否存在租户 Locality 变更操作。

    4. 在排除了目标 Zone 节点和其他非可用节点后,如果剩余节点上的副本不能满足多数派,则报错 -4179,并且展示有问题的日志流信息。

      例如:租户 1001 的 1 号日志流在 STOP ZONE 后不能满足多数派,则报错信息为 Tenant(1001) LS(1) has no enough valid paxos member after stop zone, stop zone not allowed。如果遇到该错误信息,可以通过查询 GV$OB_LOG_STAT 视图,确认日志流的成员列表和副本信息是否满足多数派。

  3. STOP ZONE 保证成功执行后,还能够对被隔离 Zone 内的节点执行任何侵入性动作。即剩余可用节点上的副本在满足多数派的前提下,还要保证剩余可用节点中的多数派副本的日志是同步的,使得被隔离 Zone 内的节点即使停止进程后,剩余节点的日志依然能够形成多数派。

    1. 日志同步判断条件:对比日志流的 Follower 副本和 Leader 副本的最新日志位点,日志位点差距在 5 秒以内即认为日志是同步的。可以通过查询 GV$OB_LOG_STAT 视图的 END_SCN 字段,获取指定日志流的各个副本的最新日志位点。

    2. 如果不满足该条件,则报错 -4179,并且展示有问题的日志流信息。

      例如:租户 1001 的 1 号日志流日志不同步,则报错信息为 Tenant(1001) LS(1) log not sync, stop server not allowed。如果遇到该错误信息,可以通过查询 GV$OB_LOG_STAT 视图的 END_SCN 字段确认日志流副本同步情况。

    # 获取指定日志流副本的最新日志位点信息,并转换成时间戳形式
    obclient [(none)]> SELECT SCN_TO_TIMESTAMP(END_SCN) FROM GV$OB_LOG_STAT WHERE TENANT_ID = 1001 and LS_ID = 1;
    

STOP ZONE 是最安全的隔离命令,但同时它的前置条件也是最严格的。在实际应用中,特别是故障应急场景下,可能无法完全满足上述前置条件,进而导致 STOP ZONE 命令无法执行成功。因此 OceanBase 数据库提供了另外两种 Zone 隔离命令:FORCE STOP ZONE 和 ISOLATE ZONE。他们不同程度的放松了前置检查,减少了限制,从而在更多场景下能够成功隔离 Zone,但 Zone 被隔离后的操作有所限制。任何场景下都应该首选 STOP ZONE 命令,STOP ZONE 无法成功的情况下可以选择弱化版本的 Zone 隔离命令,但弱化版本的 Zone 隔离后能够执行的操作会有所限制。

FORCE STOP ZONE

相比于 STOP ZONE 命令,FORCE STOP ZONE 跳过了日志同步检查。FORCE STOP ZONE 命令能够保证将业务流量从被隔离 Zone 内的节点上切走,但不能保证被隔离 Zone 内的节点能够安全的停止进程。强行停止进程后可能破坏 Paxos 多数派,从而影响数据库服务的连续性。

FORCE STOP ZONE 的典型应用场景:某机房内的服务器或者网络设备出现硬件异常需要停机运维,为了保证隔离后能够安全的停止进程,我们首选 STOP ZONE 命令隔离机房对应的 Zone,但其他 Zone 内的节点的副本日志存在较大延迟,STOP ZONE 命令无法执行成功。我们只能退而其次选择 FORCE STOP ZONE 命令来隔离 Zone,首先避免硬件异常对业务流量造成影响。然后排查副本日志延迟的原因,待副本日志实时后再次尝试执行 STOP ZONE 命令,成功执行后可以安全的进行停机运维。

obclient [(none)]> ALTER SYSTEM FORCE STOP ZONE zone_name;

注意事项:

  1. 如果在 FORCE STOP ZONE 之后,目标 Zone 节点仍然继续参与 Paxos 日志同步,明确不会下线目标 Zone 节点,那么可以安全的使用 FORCE STOP ZONE,实现隔离故障以及切换业务流量目的。即使存在部分副本日志不同步,也不会影响服务的连续性。

  2. 如果用户希望在 FORCE STOP ZONE 之后下线目标节点,那么用户需要关注存在落后副本的日志流情况,确认目标节点下线后,是否影响该日志流提供服务,用户还可以通过查询 GV$OB_LOG_STAT 视图评估服务影响时间。

警告

FORCE STOP ZONE 仅仅适用于除了待隔离 Zone 内节点外存在其他节点日志延迟的场景,此时隔离 Zone 的目的仅仅是故障隔离,不能进行任何会造成进程停止的侵入性动作。否则会破坏 Paxos 多数派,造成租户无主,影响数据库服务的连续性。

ISOLATE ZONE

相比于 STOP ZONE 和 FORCE STOP ZONEISOLATE ZONE 的前置检查最为宽松,响应速度最快。它不保证安全性,即不保证目标 Zone 内的节点下线后,集群剩余节点的副本可以组成 Paxos 多数派继续提供服务。

obclient [(none)]> ALTER SYSTEM ISOLATE ZONE zone_name;

ISOLATE ZONE 命令前置检查放松逻辑如下:

  1. ISOLATE ZONE 命令不再限制多个 Zone 的节点同时隔离,如果已经有其他 Zone 的节点被隔离(执行任何一种隔离命令),也可以执行 ISOLATE ZONE 命令。

    典型场景:集群有三个 Zone(Z1、Z2、Z3),Z1 和 Z3 各自一个节点出现故障,需要隔离。Z1 故障节点隔离成功后,如果采用 STOP ZONE 或者 FORCE STOP ZONE 命令继续隔离 Z3 故障节点,会报错不允许同时隔离多个 Zone。此时仅能执行 ISOLATE ZONE 命令,将业务流量从故障节点上切走,隔离后不能进行任何会造成进程停止的侵入性动作。

  2. ISOLATE ZONE 命令不再检查日志流副本的多数派和日志同步情况,即使不满足相应条件,也可以执行 ISOLATE ZONE 命令。

    典型场景:日志流初始的 Paxos 成员列表为 A、B、C 三个节点,C 节点机器宕机后永久下线,日志流的成员列表变更为 A、B,处于缺副本状态。此时如果 B 节点发生硬件故障并希望隔离该节点所在的 Zone,STOP ZONE 和 FORCE STOP ZONE 均会失败,报错为剩余副本不满足多数派。此时仅能执行 ISOLATE ZONE 命令,将业务流量从故障节点上切走,隔离后不能进行任何会造成进程停止的侵入性动作。

ISOLATE ZONE 命令限制如下:

当出现多个 Zone 节点被隔离时,ISOLATE ZONE 会检查所有租户的 Primary Zone 属性,要求不能同时隔离一个租户 Primary Zone 所在地域的所有 Zone,以防止租户的读写服务切到其他地域,进而业务请求跨城访问导致耗时大幅增加。

可以通过 DBA_OB_TENANTS 视图检查租户的 Primary Zone 属性,结合 DBA_OB_ZONES 和 DBA_OB_SERVERS 视图中已经隔离的 Zone 和节点的信息,确认是否打破上述限制条件。

警告

ISOLATE ZONE 仅仅适用于除了待隔离 Zone 内节点外存在其他节点状态异常的场景,此时隔离 Zone 的目的仅仅是故障隔离,不能进行任何会造成进程停止的侵入性动作。否则会破坏 Paxos 多数派,造成租户无主,影响数据库服务的连续性。。

总结

任何场景下都应该首选 STOP ZONE 命令,成功执行后除了达成故障隔离的目的,还可以保证能够安全的对被隔离 Zone 内节点执行任何应急动作和运维动作。STOP ZONE 无法成功的情况下可以选择弱化版本的 Zone 隔离命令,但弱化版本的 Zone 隔离后不能保证能够安全的执行侵入性动作。

FORCE STOP ZONE 适用于除了待隔离 Zone 内节点外存在其他节点日志延迟的场景,ISOLATE ZONE 适用于除了待隔离 Zone 内节点外存在其他节点状态异常的场景。此时隔离 Zone 的目的仅仅是故障隔离,不能进行任何会造成进程停止的侵入性运维动作,否则会破坏 Paxos 多数派,造成租户无主,影响数据库服务的连续性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值