全部产品
Search
文档中心

云原生数据库 PolarDB:分区分裂

更新时间:Apr 26, 2024

注意事项

  • 本文要求PolarDB-X实例版本必须为5.4.14-16539836及以上;

  • 若要对二级分区进行分区分裂操作,要求PolarDB-X实例版本必须为5.4.17-16952556及以上。

  • 分裂后指定新分区的定义时,新分区必须满足原分区下的数据约束,禁止出现分裂后原有数据无法路由到任何新分区的情况。

名词解释

  • 表组:分区列完全相同的一组逻辑表或全局索引表的集合。

  • 全局索引:使用另一个维度进行水平分区的数据与主表始终保持强一致的分区表。

语法

ALTER { TABLE tbl_name | TABLEGROUP tg_name | TABLEGROUP BY TABLE tbl_name } 
		split_partition_specs_definition
 | split_subpartition_specs_definition

 
split_partition_specs_definition:
SPLIT PARTITION part_name [INTO (partition_specs_definition)]
| SPLIT PARTITION part_name into partitions partitions_count
| SPLIT PARTITION part_name at(#value) into (partition part_name, partition part_name)

split_subpartition_specs_definition:
SPLIT SUBPARTITION subpartition_name [INTO (subpartition_specs_definition)]
| SPLIT SUBPARTITION subpartition_name into subpartitions subpartitions_count
| SPLIT SUBPARTITION subpartition_name at(#value) into (subpartition subpartition_name, subpartition subpartition_name)


partition_specs_definition:
 range_partition_list
 | list_partition_list

subpartition_specs_definition:
 range_subpartition_list
 | list_subpartition_list

range_partition_list:
 ( range_partition [, range_partition, ... ] )

range_partition:
 	PARTITION partition_name VALUES LESS THAN (range_bound_value) 

# 二级分区的Range/Range Columns分区定义
range_subpartition_list:
	( range_subpartition [, range_subpartition, ... ] )

range_subpartition:
 SUBPARTITION subpartition_name VALUES LESS THAN (range_bound_value) [partition_spec_options]

list_partition_list:
 (list_partition [, list_partition ...])

list_partition:
 	PARTITION partition_name VALUES IN (list_bound_value) [partition_spec_options] 

# 二级分区的List/List Columns分区定义
list_subpartition_list:
	(list_subpartition [, list_subpartition ...])

list_subpartition:
	SUBPARTITION subpartition_name VALUES IN (list_bound_value) [partition_spec_options]
说明

其中ALTER TABLEGROUP BY TABLE tbl_name是根据表名[db_name.]tbl_name自动查找目标表的表组tg_name进行表组级的分区分裂,语义上与给定具体表组名的SQL:ALTER TABLEGROUP tg_name进行分区操作是一样的。

场景1:目标分区为不包含二级分区的一级分区

Range/Range column分区表分裂

表级用法

假设表tb1的定义为:

CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
 (PARTITION p1 VALUES LESS THAN(20), 
 PARTITION p2 VALUES LESS THAN(100))

通过以下SQL将p1分裂成p10、p11、p12:

ALTER TABLE tb1 SPLIT PARTITION p1 INTO 
(PARTITION p10 VALUES LESS THAN (8),
PARTITION p11 VALUES LESS THAN(15),
PARTITION p12 VALUES LESS THAN(20))

对于range分区表,PolarDB-X提供一个语法糖,支持将一个range在其范围内按任意点一分为二。例如对于tb1表,执行如下语法可以将分区p1分裂:

ALTER TABLE tb1 SPLIT PARTITION p1 AT(9) INTO (partition p11, partition p12)

这个sql等价于以下语句:

ALTER TABLE tb1 SPLIT PARTITION p1 INTO 
(PARTITION p11 VALUES LESS THAN(9),
PARTITION p12 VALUES LESS THAN(20));

表组级用法

说明

对表组的分区进行分裂,意味着表组内所有表的相应分区会同步进行分裂。

假设表tb1、tb2的分区定义一致,且在同一个表组mytg1(名字唯一即可,示例中全部以mytg1为例):

create tablegroup mytg1;
CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
 (PARTITION p1 VALUES LESS THAN(20), 
 PARTITION p2 VALUES LESS THAN(100)) tablegroup=mytg1;
 
CREATE TABLE tb2(a int) PARTITION BY RANGE(a)
 (PARTITION p1 VALUES LESS THAN(20), 
 PARTITION p2 VALUES LESS THAN(100)) tablegroup=mytg1; 

可以通过以下SQL将表组mytg1的p1分裂成p10、p11、p12(意味着tb1和tb2的分区p1会被同步的分裂成p10、p11、p12):

ALTER TABLEGROUP mytg1 SPLIT PARTITION p1 INTO 
(PARTITION p10 VALUES LESS THAN (8),
PARTITION p11 VALUES LESS THAN(15),
PARTITION p12 VALUES LESS THAN(20))

对于range分区表表组,PolarDB-X提供一个语法糖,支持将一个range在其范围内按任意点一分为二。例如对于表组mytg1,执行如下语法可以将分区p1分裂:

ALTER TABLEGROUP mytg1 SPLIT PARTITION p1 AT(9) INTO (partition p11, partition p12)

这个SQL等价于以下语句:

ALTER TABLEGROUP mytg1 SPLIT PARTITION p1 INTO 
(PARTITION p11 VALUES LESS THAN(9),
PARTITION p12 VALUES LESS THAN(20));

List/List column分区表分裂

表级用法

假设表tb1的定义为:

CREATE TABLE tb1(a int) PARTITION BY LIST(a)
 (PARTITION p1 VALUES IN(1, 2, 3, 4, 5, 6), 
 PARTITION p2 VALUES IN(7,8,9),
 PARTITION p3 VALUES IN(default))

执行以下SQL可以将p1分裂成p10、p11、p12:

ALTER TABLE tb1 SPLIT PARTITION p1 INTO 
(PARTITION p10 VALUES IN (1,3,5),
PARTITION p11 VALUES IN (2,4),
PARTITION p12 VALUES IN (6))

对于分区p3,它是default分区,意味着1~9之外的分区键对应的值全部落到它上面,对于default分区,PolarDB-X也允许将部分value从default分区中分裂出来,例如将10~15从p3中分裂出来:

ALTER TABLE tb1 SPLIT PARTITION p3 INTO 
(PARTITION p30 VALUES IN (10,11,12),
PARTITION p31 VALUES IN (13,14,15),
PARTITION p32 VALUES IN (default))

表组级用法

说明

对表组的分区分裂,意味着表组内所有表的相应分区会同步进行分裂。

假设表tb1、tb2的分区定义一致,且在一个表组mytg1(名字唯一即可,实例中全部以mytg1为例):

create tablegroup mytg1;
CREATE TABLE tb1(a int) PARTITION BY LIST(a)
 (PARTITION p1 VALUES IN(1, 2, 3, 4, 5, 6), 
 PARTITION p2 VALUES IN(7,8,9),
 PARTITION p3 VALUES IN(default)) tablegroup=mytg1;
 
CREATE TABLE tb2(a int) PARTITION BY LIST(a)
 (PARTITION p1 VALUES IN(1, 2, 3, 4, 5, 6), 
 PARTITION p2 VALUES IN(7,8,9),
 PARTITION p3 VALUES IN(default)) tablegroup=mytg1; 

可以通过以下SQL将p1分裂成p10、p11、p12(意味着tb1和tb2的分区p1会被同步的分裂成p10、p11、p12):

ALTER TABLEGROUP mytg1 SPLIT PARTITION p1 INTO 
(PARTITION p10 VALUES IN (1,3,5),
PARTITION p11 VALUES IN (2,4),
PARTITION p12 VALUES IN (6))

对于分区p3,它是default分区,意味着1~9之外的分区键对应的值全部落到它上面,对于default分区,PolarDB-X也允许将部分value从default分区中分裂出来,例如将10~15从p3中分裂出来:

ALTER TABLEGROUP mytg1 SPLIT PARTITION p3 INTO 
(PARTITION p30 VALUES IN (10,11,12),
PARTITION p31 VALUES IN (13,14,15),
PARTITION p32 VALUES IN (default))

Hash/key分区表分裂

表级用法

假设表tb1的定义为:

CREATE TABLE tb1(a int) PARTITION BY key(a) partitions 3;

默认的三个分区的名字依次是p1、p2、p3。

执行以下SQL可以将p1分裂成两个分区,这两个新分区是在原p1的hash空间范围内将其按hash空间范围一分为二:

ALTER TABLE tb1 split partition p1

也可以将分区分裂成指定数目的多个分区。例如将p2分裂成5个分区,这5个新分区是在原p1的hash空间范围内将其按hash空间范围一分为五:

ALTER TABLE tb1 split partition p2 INTO partitions 5

表组级用法

说明

对表组的分区分裂,意味着表组内所有表的相应分区会同步进行分裂。

假设表tb1、tb2的分区定义一致,且在同一个表组mytg1(名字唯一即可,实例中全部以mytg1为例):

CREATE tablegroup mytg1;
CREATE TABLE tb1(a int) PARTITION BY key(a) partitions 3 tablegroup=mytg1;
CREATE TABLE tb2(a int) PARTITION BY key(a) partitions 3 tablegroup=mytg1;

默认的表的三个分区的名字依次是p1、p2、p3。

执行以下SQL可以将表组的p1分裂成两个分区,这两个新分区是在原p1的hash空间范围内将其按hash空间范围一分为二:

ALTER tablegroup mytg1 split partition p1

也可以将分区分裂成指定数目的多个分区,例如将p2分裂成5个分区,这5个新分区是在原p1的hash空间范围内将其按hash空间范围一分为五:

ALTER tablegroup mytg1 split partition p2 into partitions 5

场景2:目标分区为含有二级分区的一级分区

场景1中对应的分区策略的实例,同样适应于场景2。

表级用法

对于二级分区是非模板化,可以在分裂一级分区的时候重新定义子分区,例如对于以下表:

CREATE TABLE t1 (
a bigint unsigned NOT null,
b bigint unsigned NOT null,
c datetime NOT NULL,
d varchar(16) NOT NULL,
e varchar(16) NOT NULL
)
partition BY key (a,b) partitions 4
subpartition BY range columns (c,d)
(
partition p1
(
subpartition p1sp1 VALUES less than ( '2020-01-01', 'abc' ),
subpartition p1sp2 VALUES less than ( maxvalue, maxvalue )
),
partition p2
(
subpartition p2sp1 VALUES less than ( '2020-01-01', 'abc' ),
subpartition p2sp2 VALUES less than ( '2021-01-01', 'abc' ),
subpartition p2sp3 VALUES less than ( '2022-01-01', 'abc' ),
subpartition p2sp4 VALUES less than ( maxvalue, maxvalue )
),
partition p3
(
subpartition p3sp1 VALUES less than ( '2020-01-01', 'abc' ),
subpartition p3sp2 VALUES less than ( maxvalue, maxvalue )
),
partition p4
(
subpartition p4sp1 VALUES less than ( '2020-01-01', 'abc' ),
subpartition p4sp2 VALUES less than ( maxvalue, maxvalue )
)
);

和场景1一样,在分裂一级分区时可以这样执行:

ALTER TABLE t1 split partition p1;

同时也支持分裂时重新定义子分区:

ALTER TABLE t1 split partition p1 INTO (
 partition p10 (subpartition p10sp1 VALUES less than('2020-01-01', 'abc'),
 subpartition p10sp2 VALUES less than('2022-01-01', 'abc'),
 subpartition p10sp3 VALUES less than(maxvalue, maxvalue)),
 partition p11 (subpartition p11sp1 VALUES less than(maxvalue, maxvalue)));

以上命令将p1分裂成两个新的一级分区p10、p11,同时指定p10分区下包括3个子分区, p11分区下只包括1个子分区。

重要

新定义的子分区必须满足原分区下的数据约束,不能出现分裂后原有数据无法路由到任何新分区的情况。

对于二级分区是模板化分区,不允许在分裂一级分区时更改子分区的定义。

表组级用法

和表级类似,仅需将语法规则alter table #tb改成alter tablegroup #tgnamealter tablegroup by #tb

场景3:目标分区为模板化的二级分区

当二级分区是模板化分区时,可以通过分裂语法直接将某个模板二级分区分裂,分裂模板二级分区会使所有的一级分区下的子分区同时分裂。

模板化二级分区是Range/Range column策略的分区表分裂

表级用法

假设表tb1的定义为:

CREATE TABLE tb1 (
a bigint unsigned NOT null,
b bigint unsigned NOT null,
c bigint NOT NULL,
d varchar(16) NOT NULL,
e varchar(16) NOT NULL
)
partition BY key (a,b) partitions 4
subpartition BY range (c) (
 subpartition sp1 VALUES less than ( 1000 ),
 subpartition sp2 VALUES less than ( 2000 ),
 subpartition sp3 VALUES less than ( maxvalue )
);

可以通过以下SQL将sp2分裂成sp20、sp21、sp22:

ALTER TABLE tb1 split subpartition sp2 INTO 
(partition sp20 VALUES less than (1200),
partition sp21 VALUES less than(1600),
partition sp22 VALUES less than(2000))

对于range分区表,PolarDB-X提供一个语法糖,支持将一个range在其范围内按任意点一分为二,例如对于tb1表,执行以下SQL将分区sp2分裂:

ALTER TABLE tb1 split subpartition sp2 at(1600) INTO
(subpartition sp21, subpartition p22)

这个SQL等价于以下语句:

ALTER TABLE tb1 split subpartition sp2 INTO
(partition sp21 VALUES less than(1600),
partition sp22 VALUES less than(2000));

表组级用法

说明

对表组的分区分裂,意味着表组内所有表的相应分区会同步进行分裂。

和表级类似,仅需将语法规则alter table #tb改成alter tablegroup #tgnamealter tablegroup by #tb

模板化二级分区是List/List column策略的分区表分裂

表级用法

假设表tb1的定义为:

CREATE TABLE tb1 (
a bigint unsigned NOT null,
b bigint unsigned NOT null,
c datetime NOT NULL,
d varchar(16) NOT NULL,
e varchar(16) NOT NULL
)
partition BY key (a,b) partitions 4
subpartition BY list (to_days(c)) (
subpartition sp1 VALUES IN ( to_days('2020-01-01'),to_days('2020-02-01'),to_days('2020-03-01'),to_days('2020-04-01') ),
subpartition sp2 VALUES IN ( default )
);

执行以下SQL将sp1分裂成p10、p11、p12:

ALTER TABLE tb1 split subpartition sp1 INTO 
(subpartition sp10 VALUES IN (to_days('2020-01-01')),
subpartition sp11 VALUES IN (to_days('2020-02-01'),to_days('2020-04-01')),
subpartition sp12 VALUES IN (to_days('2020-03-01')))

对于分区sp2,它是default分区,意味着列c的值除了('2020-01-01','2020-02-01', '2020-03-01', '2020-04-01')之外的分区键对应的值全部落到它上面。对于default分区,PolarDB-X也允许将部分value从default分区中分裂出来,例如将'2023-01-01','2023-02-01','2023-03-01'从sp2中分裂出来:

ALTER TABLE tb1 split subpartition sp2 INTO 
(subpartition sp20 VALUES IN (to_days('2023-01-01')),
subpartition sp21 VALUES IN (to_days('2023-02-01'),to_days('2023-03-01')),
subpartition sp22 VALUES IN (default))

表组级用法

说明

对表组的分区分裂,意味着表组内所有表的相应分区会同步进行分裂。

和表级类似,仅需将语法规则alter table #tb改成alter tablegroup #tgnamealter tablegroup by #tb

模板化二级分区是Hash/key策略的分区表分裂

表级用法

假设表tb1的定义为:

CREATE TABLE tb1 (
a bigint unsigned NOT null,
b bigint unsigned NOT null,
c datetime NOT NULL,
d varchar(16) NOT NULL,
e varchar(16) NOT NULL
)
partition BY key (c,d) partitions 3
subpartition BY key (a,b) subpartitions 3;

默认的一级分区的名字依次是p1、p2、p3,模板子分区的名称依次是sp1、sp2、sp3。

可以通过以下语法,将sp1分裂成两个分区,这两个新分区是在原sp1的hash空间范围内将其按hash空间范围一分为二:

ALTER TABLE tb1 split subpartition sp1

也可以将分区分裂成指定数目的多个分区,例如将sp2分裂成5个分区,这5个新分区是在原p1的hash空间范围内将其按hash空间范围一分为五:

ALTER TABLE tb1 split subpartition sp2 INTO subpartitions 5

表组级用法

说明

对表组的分区分裂,意味着表组内所有表的相应分区会同步进行分裂。

和表级类似,仅需将语法规则alter table #tb改成alter tablegroup #tgnamealter tablegroup by #tb

场景4:目标分区是非模板化的二级分区

说明

和场景3不一样,对于二级分区是非模板化分区,可以通过分裂语法直接将某个二级分区分裂,仅分裂该二级分区本身。

场景3中对应的分区策略的实例,同样适应于场景4,具体语法请参考场景3:目标分区为模板化的二级分区