[TOC] # 表级副本的使用 租户级副本变更操作,请参见[Locality 管理](https://open.oceanbase.com/docs/community/oceanbase-database/V3.1.0/locality-management-overview)章节。 表级副本主要通过建表时指定 Locality 属性或者`ALTER TABLE`语句指定 Locality 属性,示例语句如下所示: ~~~ CREATE TABLE table_name (...) locality='XXX,XXX,XXX'; ALTER TABLE table_name SET locality='XXX,XXX,XXX'; ~~~ ## 表级 Locality 操作范围 默认表级 Locality 为空的表,通过变更租户 Locality 可批量调整租户下所有表的副本分布。Locality 不为空的表,可通过表级 Locality 变更来调整目标表的副本分布,即表级 Locality 的变更对象为表 Locality 不为空的表。 ## 操作方式和变更进度查询 表级 Locality 的操作方式与租户级 Locality 相同,仅支持每次一个 Zone 上的 Locality 变更。并且变更后的表 Locality 仍然要满足与当前租户 Locality 的匹配限制。表级 Locality 的变更流程也与租户级 Locality 相同,但变更对象仅限于对单个目标表。变更执行后,可登录系统租户运行下述 SQL 语句以查询变更进度: ~~~ obclient> SELECt gmt_create, gmt_modified, tenant_id, table_name, job_type, job_status FROM __all_rootservice_job WHERE job_type LIKE '%LOCALITY%' ORDER BY job_id DESC; ~~~ **说明** 租户级 Locality 变更也可使用上述语句进行查询,返回结果中的`tenant id`和`table_name`列中会显示变更对象的具体值。对于表级 Locality 的变更,返回结果中的`tenant_id`为 NULL。 ## 操作注意事项 * 对表级 Locality 非空的不同目标表,Locality 变更操作可以同时进行。 * 对表级 Locality 非空的表执行 Locality 变更后,在变更未完成时不允许该表所属的租户发生 Locality 变更,即此时通过`ALTER TENANT`语句发起的租户 Locality 变更会失败。 * 对表级 Locality 非空的表,如需在 Zone 或 Region 中调整 readonly 或 memonly 等 non\_paxos 类型副本(即不参与投票的副本)的数量时,需要直接修改租户的 Locality 属性列来实现。增减 non\_paxos 副本的任务会直接交由 Rootservice 的负载均衡线程完成。 * 对表级 Locality 为空的表,如果需要在 Zone 和 Region 内增加 non\_paxos 类型副本时,可通过`ALTER TABLE`修改此表。例如,`tenant Locality=F@z1,F@z2,F@z3`中有一个 Locality 为空的表,通过`ALTER TABLE`修改为`Locality=F@z1,F@z2,R@z3`后该表的 Locality 不再为空。同样增减 non\_paxos 副本的任务也是直接交由 Rootservice 的负载均衡线程完成。 * 不支持将 Locality 非空的表修改为空。 * sys 租户系统表的 Locality 都必须与 sys 租户的 Locality 保持一致,即系统表的 Locality 始终为空,不支持修改系统表中表级的 Locality 修改。 * 在为整个租户的所有表增加、减少或修改 Locality 时需要执行如下两步操作: 1. 对租户 Locality 做变更。 2. 对租户下所有不为空的表 Locality 做变更。 在完成第一步租户 Locality 的变更后必须人工进行第二步表 Locality 的变更,如果越过第二步进行下一轮的租户 Locality 变更,将产生不可预知的错误。 ## 示例 假设集群在杭州有三个机房分别为 hz1@Hangzhou、hz2@Hangzhou 和 hz3@Hangzhou。且租户的默认三个全功能 Locality 分别设定为 F@hz1、F@hz2 和 F@hz3。 当需要定义一个表,且要求其只读副本部署在集群中所有 OBServer 节点上时,可以通过下述的 SQL 语句进行创建: ~~~ CREATE TABLE table_name (...) locality = 'F@hz1, F@hz2, F@hz3, R{all_server}@hz1, R{all_server}@hz2, R{all_server}@hz3'; ~~~ 也可通过下述的`ALTER TABLE`语句进行修改: ~~~ ALTER TABLE table_name set locality = 'F@hz1, F@hz2, F@hz3, R{all_server}@hz1, R{all_server}@hz2, R{all_server}@hz3'; ~~~ 执行后等待`__all_rootservice_job`表中对应任务记录状态变为**SUCCESS**,即说明创建或修改完成。 **注意** 表级 Locality 的变更与租户级 Locality 变更具有如下制约关系: * 在旧的一轮租户级 Locality 没有完成变更时,新一轮的租户级 Locality 变更不允许被执行。 * 当租户下 Locality 不为空的表的变更没有完成时,租户级 Locality 变更不允许执行。 * 当租户在目标 Zone 的 Locality 变更没有发起时,Locality 不为空的表在目标 Zone 的 Locality 变更不允许执行。 综上所述,租户级 Locality 变更不允许同时发起多轮变更,租户和表的 Locality 变更前需要先完成未完成的变更