首批通过分布式安全可靠测评,为关键业务系统打造
日志流均衡会转移哪种类型的表
更新时间:2026-06-12 08:51
日志流均衡不同于分区均衡,其目的是调整日志流的数量以符合要求,而对分区的具体分布并没有严格要求。下面将讲解日志流均衡会转移哪些表。
详细说明
日志流均衡和分区均衡都是负载均衡其中的一个动作,我们简单的讲解一下负载均衡。
负载均衡
OceanBase 数据库 V4.x 版本日志流是容灾处理的最小单元,是承载分区的容器,V4.x 版本基于 Transfer 能力,实现了日志流数量、分区分布的动态调整,支持租户级别上的水平扩缩容和分区均衡。负载均衡模块会首先会对日志流数目和 Leader 进行均衡,在日志流均衡的基础之上,负载均衡模块会对分区进行均衡,实现日志流之间分区数目的均衡,以及日志流之间分区数据大小的均衡。
负载均衡例子
以调整 primary zone 为例,初始时 unit_num = 1 primary zone 为 zone1, zone2;zone3 的环境下, 有两个日志流,每个日志流上有 150 个分区。
SELECT ls_id, role, count(*) FROM oceanbase.DBA_OB_TABLE_LOCATIONS where table_type='user table' and role = 'LEADER' group by ls_id;
+-------+--------+----------+
| ls_id | role | count(*) |
+-------+--------+----------+
| 1001 | LEADER | 150 |
| 1007 | LEADER | 150 |
+-------+--------+----------+
租户将 primary zone 调整为 zone1,zone2,zone3,primary zone 的数目由 2 变为 3,会触发负载均衡任务。
obclient [oceanbase]> alter tenant mysql set primary_zone='zone1,zone2,zone3';
obclient [oceanbase]> select * from DBA_OB_BALANCE_JOB_HISTORY order by job_id desc;
+---------+----------------------------+----------------------------+----------------------+-------------------+-----------------+-------------------------+-----------+---------+
| JOB_ID | CREATE_TIME | FINISH_TIME | BALANCE_STRATEGY | JOB_TYPE | TARGET_UNIT_NUM | TARGET_PRIMARY_ZONE_NUM | STATUS | COMMENT |
+---------+----------------------------+----------------------------+----------------------+-------------------+-----------------+-------------------------+-----------+---------+
| 3767176 | 2025-05-22 15:42:20.234546 | 2025-05-22 15:42:50.243244 | partition balance | PARTITION_BALANCE | 1 | 3 | COMPLETED | NULL |
| 3766948 | 2025-05-22 15:31:43.372344 | 2025-05-22 15:32:10.456466 | LS balance by expand | LS_BALANCE | 1 | 3 | COMPLETED | NULL |
+---------+----------------------------+----------------------------+----------------------+-------------------+-----------------+-------------------------+-----------+---------+
obclient [oceanbase]> select job_id, task_id, task_type, src_ls, dest_ls from DBA_OB_BALANCE_TASK_HISTORY where job_id in
(3767176, 3766948);
+---------+---------+-------------+--------+---------+
| job_id | task_id | task_type | src_ls | dest_ls |
+---------+---------+-------------+--------+---------+
| 3766948 | 3766950 | LS_SPLIT | 1001 | 1009 |
| 3766948 | 3766952 | LS_SPLIT | 1007 | 1010 |
| 3766948 | 3766953 | LS_MERGE | 1010 | 1009 |
| 3767176 | 3767177 | LS_TRANSFER | 1009 | 1001 |
| 3767176 | 3767178 | LS_TRANSFER | 1009 | 1007 |
+---------+---------+-------------+--------+---------+
首先生成 日志流均衡 balance job 3766948,对应一组 balance task:LS_SPLIT(1001, 1009, 51),从日志流 1001 分裂出一个含有 51 个分区的日志流1009;LS_SPLIT(1007, 1010, 51),从日志流 1007 分裂出一个含有 51 个分区的日志流 1010;LS_MERGE(1010, 1009),将日志流 1010 合并到 1009 上,这样子就满足了 3 条日志流 1001,1007,1009 符合修改后的 primary_zone。 日志流均衡后,各日志流上的分区数为 99,99,102,分区不均衡,会生成 分区均衡 balance job 3767176,对应 2 个 balance task:LS_TRANSFER(1009, 1001, 1),从日志流 1009 向 1001 迁移一个分区,LS_TRANSFER(1009, 1007,1),从日志流 1009 向 1007 迁移一个分区,迁移完成后,各日志流上的分区数为 100,100,100,分区数目均衡。
SELECT ls_id, role, count(*) FROM oceanbase.DBA_OB_TABLE_LOCATIONS where table_type='user table' and role = 'LEADER' group by ls_id;
+-------+--------+----------+
| ls_id | role | count(*) |
+-------+--------+----------+
| 1001 | LEADER | 100 |
| 1007 | LEADER | 100 |
| 1009 | LEADER | 100 |
+-------+--------+----------+
日志流均衡和分区均衡
日志流均衡: 它是为了保证日志流数目符合要求,对租户执行 unit_num 变更、修改 primary_zone 的第一优先级等操作时,变更日志流的数量和位置,实现用户修改后的日志流数量的均衡,使得 ls_num=unit_num * first_level_primary_zone_num,而对于日志流均衡后分区是否均衡是没有明确要求的,他会按照比例转移符合要求的分区。
分区均衡: 在日志流均衡的基础上,负载均衡模块会通过 Transfer,将分区打散或聚合在不同 LS 上,达到租户下各日志流分区数量的均衡,在数量均衡的基础上,还会通过交换分区的方式,实现各日志流磁盘大小的相对均衡。分区均衡细分为分区属性对齐,分区权重均衡,分区数量均衡,分区磁盘均衡。
分区分配
OceanBase 数据库内部引入了分区组(Partition Group)描述分区聚合的关系,引入了均衡组(Balance Group)描述了分区打散的关系,同时向用户提供了 Table Group 机制,描述一组表中的分区聚合和打散的关系。下面简单介绍一下这几种表:
分区组(Partition Group)
OceanBase 数据库系统内部的逻辑概念,描述的是分区聚合的关系。Partition Group中的所有分区会分布在同一日志流上。
均衡组(Balance Group)
OceanBase 数据库系统内部的逻辑概念,描述的是分区打散的关系。Balance Group 由 Partition Group 组成,分区分配时,会将均衡组中的分区组按照 Round Robin 方式分布在各个日志流上。
表组(Table Group)
Table Group 是OB提供给用户的机制,Table Group 为一组表的集合,所以表组对多个表才有意义,用户可以通过 Table Group 把多个表聚集和打散的关系,Table Group 有 SHARDING 属性,包含三种取值:NONE、PARTITION、ADAPTIVE。
SHARDING = NONE
Table Group 中可以是任意分区类型的表,包括非分区表、一级分区表、二级分区表。
表组中的所有分区形成一个 Partition Group,从而聚集到同一日志流上。

例如
p0sp0,p0sp1,p1sp0,p1sp1 为一个SHARDING = NONE的表组(tg3);p0,p1是一个SHARDING = NONE的表组(tg2);所有SHARDING = NONE的表组的表的分区都放在一个日志流中。ls0 ls1 ls2 新建非分区表(tg1) p0 新建一级分区表(tg2) p0, p1 新建二级分区表(tg3) p0sp0, p0sp1
p1sp0, p1sp1
SHARDING = PARTITION
Table Group 里所有表都会看成是一级分区表,要求所有表的一级分区方式相同。
表组中按照一级分区为 Partition Group 聚合在同一日志流,一级分区打散二级分区聚合。

例如,两张表二级分区表
t0,t1放入表组tg2中,t0p0sp0,t0p0sp1,t1p0sp0,t1p0sp1为一个 Partition Group 聚集在同一个日志流中;Partition Group 以 Round Robin 的方式分配到各日志流上。ls0 ls1 ls2 一级分区表(tg1) t0p0, t1p0 t0p1,t1p1 t0p2,t0p2 二级分区表(tg2) t0p0sp0
t0p0sp1
t1p0sp0
t1p0sp1t0p1sp0
t0p1sp1
t1p1sp0
t1p1sp1t0p2sp0
t0p2sp1
t1p2sp0
t1p2sp1
SHARDING = ADAPTIVE
要求表全部是一级分区表或者全都是二级分区表。
如果全都是 1 级分区和
SHARDING = PARTITION类似,一级分区打散。
如果全都是二级分区,以一级分区为 Balance Group 以二级分区为 Partition Group,把二级分区打散在不同的日志流中。

例如,有二级分区表
t0,t1在表组tg2中,一级分区p0为一个 Balance Group,二级分区为 Partition Group,将表组里面表的二级分区打散。ls0 ls1 ls2 一级分区表(tg1) t0p0, t1p0 t0p1, t1p1 t0p2, t1p2 二级分区表(tg2) t0p0sp0
t1p0sp0t0p0sp1, t1p0sp1 t0p0sp2,
t1p0sp2t0p1sp3
t1p1sp3t0p1sp0
t1p1sp0t0p1sp1
t1p1sp1
非表组表
租户下所有的非分区表形成一个均衡组,所有非分区表被打散到各日志流上(有点像每个非分区表像是一个 Partition Group)。
租户下的每个一级分区表形成一个均衡组,一级分区表每个分区形成一个 Partition Group,所有的 Partition Group 形成一个均衡组,就是按照一级分区打散(分区方式类似表组
SHARDING = PARTITION里只有一张表)。租户下的每个二级分区表形成多个均衡组,均衡组的数目和一级分区的数目相同,每个一级分区下的每个二级分区形成一个 Partition Group,每个一级分区下的所有 Partition Group 形成一个均衡组(分区方式类似表组
SHARDING = ADAPTIVE里面有只一张表)。
日志流均衡无法转移的表
回归正题,日志流均衡所要转移的表需要从代码中一探究竟。

简单解释一下,日志流均衡会遍历这个日志流所有的 balance_group 来看 transfer 走多少 partition_group,上面就是计算代码。 total_count: 还没有 transfer_out 前这条日志流中这个 balance_group 中的 partition_group 的数目。 factor: 是要从这个日志流中 transfer 的比例。 avail_count: 现在这条日志流这个 balance_group 中 partiton_group 的个数。
通过上面的代码可知 balance_group 中只有一个 partition_group 时是不会被日志流均衡 transfer 走的(上图带入数字 remove_count = min(0,1) = 0)。
只有一个 partition_group 的表的特征:
当表组的分片方式为
SHARDING = NONE时,无论表组内包含多少张表,都只有一个 partition_group,因此无法被转移。对于单一级分区表(例如:
CREATE TABLE xxx PARTITION BY xxx PARTITIONS 1),无论是否被放入表组,也无法被转移。单二级分区表(例如:
CREATE TABLE xxx PARTITION BY xxx PARTITIONS xxx SUBPARTITION BY xxx SUBPARTITIONS 1),如果不在表组中,或在分片方式为SHARDING = ADAPTIVE的表组中,同样无法被转移。如果某个表组的分片方式为
SHARDING = PARTITION,并且其中包含单一级分区的二级分区表(例如:CREATE TABLE xxx PARTITION BY xxx PARTITIONS 1 SUBPARTITION BY xxx SUBPARTITIONS xxx),该表也无法被转移。
当日志流均衡后这些表并不会被均衡走,也就是说可能做了扩容,但是流量还是并没有切走,可以进行如下的操作:
可以修改配置项
partition_balance_schedule_interval,这个控制分区均衡的时间间隔默认 2h。可以修改这个时间短一点让其快点触发分区均衡(能采用手动分区就采用手动分区,因为这个并不会一次性执行完分区均衡的 4 个细分的均衡)。alter system set partition_balance_schedule_interval = '10s';OceanBase 数据库 V4.2.1 BP9 版本和 V4.2.4 版本中可以直接手动调用分区均衡(建议)。
// mysql模式 CALL DBMS_BALANCE.TRIGGER_PARTITION_BALANCE(); // 触发 1 次分区均衡,后台均衡任务无超时时间,做完为止。 CALL DBMS_BALANCE.TRIGGER_PARTITION_BALANCE(7200); // 触发分区均衡后,后台均衡任务最多运行 2h,做不完超时取消。 // oracle模式 BEGIN DBMS_BALANCE.TRIGGER_PARTITION_BALANCE(); // 触发 1 次分区均衡,后台均衡任务无超时时间,做完为止。 COMMIT; END; BEGIN DBMS_BALANCE.TRIGGER_PARTITION_BALANCE(7200); // 触发分区均衡后,后台均衡任务最多运行 2h,做不完超时取消。 COMMIT; END;
适用版本
OceanBase 数据库 V4.x 版本。