首批通过分布式安全可靠测评,为关键业务系统打造
增加副本
更新时间:2026-02-25 09:25:52
本文介绍如何增加租户下日志流的副本数。
通过修改 Locality 增加副本
通过修改集群中某个租户的 Locality,可以增加该租户下日志流的副本数。有关修改 Locality 的详细操作和注意事项,参见 修改 Locality。
前提条件
增加副本之前,首先需要确认租户在目标 Zone 上是否有资源池,如果没有,则需要调整现有资源池的 Zone 列表,或者新增一个资源池给租户,如果新增资源池,要求资源池的 Unit 个数与租户已有的资源池一致,调整资源池或新增资源池的详细操作,参见 修改资源池属性 或 创建资源池。
同时还需要确认待变更的 Zone 上各节点的资源分配情况。如果 Zone 上的节点资源不足导致无法存放租户需要的资源单元,将导致无法进行 Locality 变更。
有关 Zone 上各节点的资源分配情况,请参见 查看租户和资源信息。
注意事项
租户的 Locality 不可以为空。
当租户的 Locality 发生变更时,在该租户下,所有表的副本分布情况也会随之变化。
在旧一轮租户 Locality 没有完成变更时,新一轮的租户 Locality 变更不允许被执行。
Locality 变更一次只能执行一个动作,例如把 Zone3 替换为 Zone4,不能直接替换,可以先增加一个 Zone4,然后再减少一个 Zone3。
修改 Locality 时需要关注对 Primary Zone 的影响,建议提前调整 Primary Zone。
例如:
需要减少 zone3,如果 zone3 属于第一优先级的 Primary Zone,则调整 Locality 过程会影响租户读写服务。
增加 zone4 时,如果 Primary Zone 为 RANDOM,那么后续 zone4 也会提供读写服务。
操作步骤
示例:通过修改租户 mysql001 的 Locality,由 FULL{1}@zone1, FULL{1}@zone2 修改为 FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3,在 zone3 上为租户新增副本。
说明
此处仅以添加 1 个 Zone 为示例,实际操作中注意添加的 Zone 的数量需要能够满足多数派原则。
使用 root 用户登录到集群的 sys 租户。
obclient -h172.30.xxx.xxx -P2883 -uroot@sys#obdemo -pxxxx -A进入
oceanbase数据库。obclient(root@sys)[(none)]> USE oceanbase;查看租户
mysql001修改前的 Locality。obclient(root@sys)[oceanbase]> SELECT TENANT_ID,TENANT_NAME,TENANT_TYPE,PRIMARY_ZONE,LOCALITY FROM oceanbase.DBA_OB_TENANTS;查询结果如下:
+-----------+-------------+-------------+-------------------+---------------------------------------------+ | TENANT_ID | TENANT_NAME | TENANT_TYPE | PRIMARY_ZONE | LOCALITY | +-----------+-------------+-------------+-------------------+---------------------------------------------+ | 1 | sys | SYS | zone1;zone2;zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | | 1001 | META$1002 | META | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2 | | 1002 | mysql001 | USER | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2 | +-----------+-------------+-------------+-------------------+---------------------------------------------+ 3 rows in set可以看到租户
mysql001分别在 zone1 和 zone2 上有一个全能型副本。修改租户
mysql001的 Locality。obclient(root@sys)[oceanbase]> ALTER TENANT mysql001 locality="FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3";查看 Locality 变更任务的执行状态。
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_TENANT_JOBS WHERE JOB_TYPE = 'ALTER_TENANT_LOCALITY';查询结果如下:
+--------+-----------------------+------------+-------------+----------+----------------------------+----------------------------+-----------+------------------------------------------------------------------------------+---------------------------------------------+----------------+-------------+ | JOB_ID | JOB_TYPE | JOB_STATUS | RESULT_CODE | PROGRESS | START_TIME | MODIFY_TIME | TENANT_ID | SQL_TEXT | EXTRA_INFO | RS_SVR_IP | RS_SVR_PORT | +--------+-----------------------+------------+-------------+----------+----------------------------+----------------------------+-----------+------------------------------------------------------------------------------+---------------------------------------------+----------------+-------------+ | 1 | ALTER_TENANT_LOCALITY | SUCCESS | NULL | 0 | 2023-01-05 19:38:38.416011 | 2023-01-05 19:38:38.416011 | 1002 | ALTER TENANT mysql001 locality='FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3' | FULL{1}@zone1, FULL{1}@zone2 | xx.xx.xx.237 | 2882 | +--------+-----------------------+------------+-------------+----------+----------------------------+----------------------------+-----------+------------------------------------------------------------------------------+---------------------------------------------+----------------+-------------+ 1 row in set当
JOB_STATUS为SUCCESS时,则说明 Locality 变更任务执行成功。查看租户
mysql001修改后的 Locality。obclient(root@sys)[oceanbase]> SELECT TENANT_ID,TENANT_NAME,TENANT_TYPE,PRIMARY_ZONE,LOCALITY FROM oceanbase.DBA_OB_TENANTS;查询结果如下:
+-----------+-------------+-------------+-------------------+---------------------------------------------+ | TENANT_ID | TENANT_NAME | TENANT_TYPE | PRIMARY_ZONE | LOCALITY | +-----------+-------------+-------------+-------------------+---------------------------------------------+ | 1 | sys | SYS | zone1;zone2;zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | | 1001 | META$1002 | META | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | | 1002 | mysql001 | USER | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | +-----------+-------------+-------------+-------------------+---------------------------------------------+ 3 rows in set通过步骤 3 与步骤 6 的查询比较,租户
mysql001的 Locality 由原来的FULL{1}@zone1, FULL{1}@zone2变为FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3,租户mysql001在 zone1、zone2、zone3 上分别有一个全能型副本。
通过增加副本会导致租户 Locality 与租户 Primary Zone 不匹配,如果增加的 Zone 参与切主,则需要修改 Primary Zone,关于修改 Primary Zone 的操作,参见 调整 Primary Zone;如果增加的 Zone 不参与切主,则不需要修改 Primary Zone。
手动添加副本
当通过修改 Locality 增加副本时,正常情况下,系统会自动补充缺少的副本,但由于一些异常原因,导致系统未正常工作,可以通过 ALTER SYSTEM ADD REPLICA 命令手动添加缺少的日志流副本。
使用限制
系统租户(sys 租户)可以对所有租户的日志流执行添加副本操作,用户租户只能对本租户的日志流执行添加副本操作。
租户的同一个日志流,除了副本迁移任务可以并行执行多个以外,其他容灾任务(包括添加副本、删除副本、转换副本类型、修改日志流的法定成员数等)每次只能执行一个。
sys 租户可以通过视图
CDB_OB_LS_REPLICA_TASKS确认是否有正在运行的容灾任务;用户租户可以通过视图DBA_OB_LS_REPLICA_TASKS确认是否有正在运行的容灾任务。
前提条件
在执行添加副本操作前,请确认当前用户拥有
ALTER SYSTEM权限,否则无法执行ALTER SYSTEM ADD REPLICA命令。在查询视图前,请确认当前用户拥有以下视图的
SELECT权限,否则无法查询相关信息。DBA_OB_TENANTSDBA_OB_LS/CDB_OB_LSGV$OB_UNITSDBA_OB_LS_LOCATIONS/CDB_OB_LS_LOCATIONS
在执行添加副本操作前,需要保证目标服务器上有用户可用的资源即 Unit,并确保该 Unit 上没有该日志流的副本。
操作步骤
假设当前有一个 tenant1 租户,其 Locality 为 F@zone1,F@zone2,F@zone3,同时,tenant1 租户的 1001 号日志流仅在 zone1 和 zone3 各有一个 F 类型的副本,在 zone2 没有副本。现在需要手动在 zone2 上补充一个 F 副本。
用户登录到集群对应的租户。
连接示例如下:
obclient -h172.30.xxx.xxx -P2883 -uroot@tenant1#obdemo -pxxxx -A有关更加详细的连接数据库的操作指引,参见 连接数据库概述(MySQL 模式) 和 连接数据库概述(Oracle 模式)。
获取待操作租户的租户 ID 及 Locality 信息。
系统租户
obclient(root@sys)[oceanbase]> SELECT TENANT_NAME,TENANT_ID,LOCALITY FROM oceanbase.DBA_OB_TENANTS WHERE TENANT_NAME='tenant1';用户租户
MySQL 模式Oracle 模式MySQL 模式下执行以下语句:
obclient(root@tenant1)[oceanbase]> SELECT TENANT_NAME,TENANT_ID,LOCALITY FROM oceanbase.DBA_OB_TENANTS;Oracle 模式下执行以下语句:
obclient(SYS@tenant1)[SYS]> SELECT TENANT_NAME,TENANT_ID,LOCALITY FROM SYS.DBA_OB_TENANTS;查询结果的示例如下:
+-------------+-----------+---------------------------------------------+ | TENANT_NAME | TENANT_ID | LOCALITY | +-------------+-----------+---------------------------------------------+ | tenant1 | 1002 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | +-------------+-----------+---------------------------------------------+ 1 row in set根据查询结果,该租户对应的租户 ID 为
1002。有关视图
DBA_OB_TENANTS中各字段的详细说明,请参见 DBA_OB_TENANTS。
获取待操作租户的所有日志流信息。
系统租户
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.CDB_OB_LS WHERE TENANT_ID=1002;有关视图
CDB_OB_LS中各字段的详细说明,请参见 CDB_OB_LS。用户租户
MySQL 模式Oracle 模式MySQL 模式下执行以下语句:
obclient(root@tenant1)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_LS;Oracle 模式下执行以下语句:
obclient(SYS@tenant1)[SYS]> SELECT * FROM SYS.DBA_OB_LS;查询结果的示例如下:
+-------+--------+-------------------+---------------+-------------+---------------------+----------+---------------------+---------------------+------+ | LS_ID | STATUS | PRIMARY_ZONE | UNIT_GROUP_ID | LS_GROUP_ID | CREATE_SCN | DROP_SCN | SYNC_SCN | READABLE_SCN | FLAG | +-------+--------+-------------------+---------------+-------------+---------------------+----------+---------------------+---------------------+------+ | 1 | NORMAL | zone1;zone3;zone2 | 0 | 0 | NULL | NULL | 1712137184525565000 | 1712137184525565000 | | | 1001 | NORMAL | zone1;zone3;zone2 | 1001 | 1001 | 1711951923021132001 | NULL | 1712137184292359002 | 1712137184292359002 | | +-------+--------+-------------------+---------------+-------------+---------------------+----------+---------------------+---------------------+------+ 2 rows in set根据查询结果可知,tenant1 租户有一个 1 号日志流和一个 1001 号日志流。
有关视图
DBA_OB_LS中各字段的详细说明,请参见 DBA_OB_LS。
获取待操作租户的 Unit 资源。
系统租户
obclient(root@sys)[oceanbase]> SELECT SVR_IP, SVR_PORT, UNIT_ID, TENANT_ID, ZONE, ZONE_TYPE, STATUS FROM oceanbase.GV$OB_UNITS WHERE TENANT_ID=1002;用户租户
MySQL 模式Oracle 模式MySQL 模式下执行以下语句:
obclient(root@tenant1)[oceanbase]> SELECT SVR_IP, SVR_PORT, UNIT_ID, TENANT_ID, ZONE, ZONE_TYPE, STATUS FROM oceanbase.GV$OB_UNITS;Oracle 模式下执行以下语句:
obclient(SYS@tenant1)[SYS]> SELECT SVR_IP, SVR_PORT, UNIT_ID, TENANT_ID, ZONE, ZONE_TYPE, STATUS FROM SYS.GV$OB_UNITS;查询结果的示例如下:
+----------------+----------+---------+-----------+-------+-----------+--------+ | SVR_IP | SVR_PORT | UNIT_ID | TENANT_ID | ZONE | ZONE_TYPE | STATUS | +----------------+----------+---------+-----------+-------+-----------+--------+ | 172.xx.xxx.226 | 2882 | 1001 | 1002 | zone1 | ReadWrite | NORMAL | | 172.xx.xxx.212 | 2882 | 1002 | 1002 | zone2 | ReadWrite | NORMAL | | 172.xx.xxx.192 | 2882 | 1003 | 1002 | zone2 | ReadWrite | NORMAL | +----------------+----------+---------+-----------+-------+-----------+--------+ 3 rows in set根据查询结果可知,当前租户在
172.xx.xxx.226:2882、172.xx.xxx.212:2882、172.xx.xxx.192:2882这 3 台服务器上均有可用的 Unit 资源。有关视图
GV$OB_UNITS中各字段的详细说明,请参见 GV$OB_UNITS。
根据前面获取到的租户的日志流信息,查看 1001 号日志流的副本分布。
系统租户
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE LS_ID=1001 AND TENANT_ID=1002;有关视图
CDB_OB_LS_LOCATIONS中各字段的详细说明,请参见 CDB_OB_LS_LOCATIONS。用户租户
MySQL 模式Oracle 模式MySQL 模式下执行以下语句:
obclient(root@tenant1)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;Oracle 模式下执行以下语句:
obclient(SYS@tenant1)[SYS]> SELECT * FROM SYS.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;查询结果的示例如下:
+----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+------------------------------------------------------------+----------------------+--------------+--------------+---------+ | CREATE_TIME | MODIFY_TIME | LS_ID | SVR_IP | SVR_PORT | SQL_PORT | ZONE | ROLE | MEMBER_LIST | PAXOS_REPLICA_NUMBER | REPLICA_TYPE | LEARNER_LIST | REBUILD | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+------------------------------------------------------------+----------------------+--------------+--------------+---------+ | 2024-04-03 17:23:06.381521 | 2024-04-03 17:32:49.079886 | 1001 | 172.xx.xxx.192 | 2882 | 2881 | zone3 | FOLLOWER | NULL | NULL | FULL | | FALSE | | 2024-04-01 14:12:08.589084 | 2024-04-03 17:32:49.124409 | 1001 | 172.xx.xxx.226 | 2882 | 2881 | zone1 | LEADER | 172.xx.xxx.192:2882:1712136186291857,172.xx.xxx.226:2882:1 | 2 | FULL | | FALSE | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+------------------------------------------------------------+----------------------+--------------+--------------+---------+ 2 rows in set根据查询结果可知,租户的 1001 日志流在
172.xx.xxx.192:2882和172.xx.xxx.226:2882上均有一个 F 类型的副本。再结合上一步的查询结果,租户在
172.xx.xxx.226:2882、172.xx.xxx.212:2882、172.xx.xxx.192:2882这 3 台服务器上均有可用的 Unit 资源,而172.xx.xxx.212:2882上没有该日志流的副本。需要在172.xx.xxx.212:2882机器上为租户的 1001 号日志流添加一个 F 类型的副本。有关视图
DBA_OB_LS_LOCATIONS中各字段的详细说明,请参见 DBA_OB_LS_LOCATIONS。
执行添加副本命令。
SQL 语句如下:
ALTER SYSTEM ADD REPLICA LS [=] ls_id SERVER [=] 'svr_ip:svr_port' REPLICA_TYPE [=] 'replica_type' [DATA_SOURCE [=] 'data_source'] [PAXOS_REPLICA_NUM [=] paxos_replica_num] [TENANT [=] 'tenant_name'];语句使用说明:
ls_id:指定待添加副本的日志流 ID。svr_ip:svr_port:指定待添加副本的目标服务器的 IP 及端口号。示例:172.xx.xxx.212:2882。replica_type:指定待添加的副本类型。当前支持以下副本类型:全功能型副本:使用
FULL或F表示。只读副本:使用
READONLY或R表示。列存副本:使用
COLUMNSTORE或C表示。
data_source:指定待添加副本的数据来源地址。示例:172.xx.xxx.192:2882。指定的数据源不可用时,系统会报错。
如果不显式指定该值,则系统会自动选择一个可用的数据源。
paxos_replica_num:指定修改后日志流的法定成员数,即租户 Locality 中全功能型(F)副本的数量。同时一个日志流的 F 副本数最多为 7 个。指定该参数的值时,需要满足以下条件:
修改后,
paxos_replica_num需要满足多数派。paxos_replica_num的值需要大于等于当前 Leader 副本中MEMBER_LIST的成员个数。paxos_replica_num值变化的绝对值不能大于 1。例如,本示例中当前paxos_replica_num为2,只能将paxos_replica_num修改为3。
如果指定的值有以上任一条件不满足,则系统会报错。如果不显式指定该值,系统将使用当前默认的
paxos_replica_num。tenant_name:指定待操作的租户。系统租户可以指定其他租户,用户租户只能指定本租户。如果不显式指定待操作的租户,则默认租户名为当前租户。本语句不支持使用all、all_user、all_meta等指定所有租户、用户租户以及所有 Meta 租户。本语句一次只能添加一个副本,如果需要补充多个副本,需要多次执行该语句。
示例如下:
obclient> ALTER SYSTEM ADD REPLICA LS= 1001 SERVER='172.xx.xxx.212:2882' REPLICA_TYPE='F' DATA_SOURCE='172.xx.xxx.192:2882' PAXOS_REPLICA_NUM=3;再次查询日志流信息,可以看到该日志流增加了一个 F 副本。
系统租户
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE LS_ID=1001 AND TENANT_ID=1002;用户租户
MySQL 模式Oracle 模式MySQL 模式下执行以下语句:
obclient(root@tenant1)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;Oracle 模式下执行以下语句:
obclient(SYS@tenant1)[SYS]> SELECT * FROM SYS.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;查询结果的示例如下:
+----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+-------------------------------------------------------------------------------------------------+----------------------+--------------+--------------+---------+ | CREATE_TIME | MODIFY_TIME | LS_ID | SVR_IP | SVR_PORT | SQL_PORT | ZONE | ROLE | MEMBER_LIST | PAXOS_REPLICA_NUMBER | REPLICA_TYPE | LEARNER_LIST | REBUILD | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+-------------------------------------------------------------------------------------------------+----------------------+--------------+--------------+---------+ | 2024-04-03 17:23:06.381521 | 2024-04-03 17:48:08.982791 | 1001 | 172.xx.xxx.192 | 2882 | 2881 | zone3 | FOLLOWER | NULL | NULL | FULL | | FALSE | | 2024-04-03 17:48:05.812041 | 2024-04-03 17:48:09.985574 | 1001 | 172.xx.xxx.212 | 2882 | 2881 | zone2 | FOLLOWER | NULL | NULL | FULL | | FALSE | | 2024-04-01 14:12:08.589084 | 2024-04-03 17:48:09.030020 | 1001 | 172.xx.xxx.226 | 2882 | 2881 | zone1 | LEADER | 172.xx.xxx.192:2882:1712136186291857,172.xx.xxx.212:2882:1712137685774460,172.xx.xxx.226:2882:1 | 3 | FULL | | FALSE | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+-------------------------------------------------------------------------------------------------+----------------------+--------------+--------------+---------+ 3 rows in set