文档

修改分区

更新时间:

注意事项

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

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

  • Hash/Key/Co_Hash的哈希分区策略,不支持执行该操作。

  • Range/Range Columns的分区策略,不支持执行该操作。

  • List/List Columns的分区策略,若分区定义使用了default等“catch-all”分区,不支持执行该分区操作。

  • 全局索引表不支持Drop Values操作。

  • 含全局索引的分区表不支持Drop Values操作。

名词解释

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

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

语法

ALTER alter_target_definition modify_partition_values_operation_definition

alter_target_definition:
		TABLE [db_name.]tbl_name
 | TABLE tbl_name.index_name
 | TABLEGROUP tg_name
 | INDEX index_name ON TABLE [db_name.]tbl_name
 | TABLEGROUP BY TABLE [db_name.]tbl_name
 | TABLEGROUP BY INDEX index_name ON TABLE [db_name.]tbl_name

modify_partition_values_operation_definition:
		MODIFY PARTITION part_name values_operation_definition
 | MODIFY SUBPARTITION subpart_name values_operation_definition

values_operation_definition:
		ADD VALUES (value_list)
 | DROP VALUES (value_list)

场景1:目标分区是一级分区

假设l_t1与l_t2都采用List分区,建表SQL如下所示:

CREATE TABLE `l_t1` (
`a` bigint(20) UNSIGNED NOT NULL,
`b` bigint(20) UNSIGNED NOT NULL,
`c` datetime NOT NULL,
`d` varchar(16) NOT NULL,
`e` varchar(16) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY LIST(YEAR(`c`)) 
(
 PARTITION p0 VALUES IN (2020,2022,2024,2026),
 PARTITION p1 VALUES IN (2021,2023,2025,2027)
);

CREATE TABLE `l_t2` (
`a` bigint(20) UNSIGNED NOT NULL,
`b` bigint(20) UNSIGNED NOT NULL,
`c` datetime NOT NULL,
`d` varchar(16) NOT NULL,
`e` varchar(16) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY LIST(YEAR(`c`)) 
(
 PARTITION p0 VALUES IN (2020,2022,2024,2026),
 PARTITION p1 VALUES IN (2021,2023,2025,2027)
);

示例1:修改一级List分区并增加Values

给l_t1表的p1分区增加2个values,新的values值是(2017,2019)。具体用法如下所示:

表级用法

## 基于表名字进行表级的分区变更操作
ALTER TABLE l_t1 /*表名*/ 
	MODIFY PARTITION p1 ADD VALUES (2017,2019);

表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即上述两个表同时执行分区变更:

## 基于表组名字进行表组级的分区变更操作, 假设表组名是tg1
ALTER TABLEGROUP tg1 /*表组名*/ 
	MODIFY PARTITION p1 ADD VALUES (2017,2019);

## 基于表名进行表组级的分区变更操作(即基于表名自动找查对应的表组并进行操作)
ALTER TABLEGROUP BY TABLE l_t1 /*表名*/ 
	MODIFY PARTITION p1 ADD VALUES (2017,2019);

示例2:修改一级List分区并删除Values

给l_t1表的p1分区删除两个values,这两个values是2021与2025。具体用法如下所示:

表级用法

## 基于表名字进行表级的分区变更操作
ALTER TABLE l_t1 /*表名*/ 
	MODIFY PARTITION p1 DROP VALUES (2021,2025);

表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即上述两个表同时执行分区变更:

## 基于表组名字进行表组级的分区变更操作
ALTER TABLEGROUP tg1 /*表组名*/ 
	MODIFY PARTITION p1 DROP VALUES (2021,2025);

## 基于表名进行表组级的分区变更操作(即基于表名自动找查对应的表组并进行操作)
ALTER TABLEGROUP BY TABLE l_t1 /*表名*/ 
	MODIFY PARTITION p1 DROP VALUES (2021,2025);

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

假设k_l_tp_t1与k_l_tp_t2都采用Key+List的二级分区,建表SQL如下所示:

CREATE TABLE `k_l_tp_t1` (
`a` bigint(20) UNSIGNED NOT NULL,
`b` bigint(20) UNSIGNED NOT NULL,
`c` datetime NOT NULL,
`d` varchar(16) NOT NULL,
`e` varchar(16) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`) PARTITIONS 2 
SUBPARTITION BY LIST(YEAR(`c`)) 
(
 SUBPARTITION sp0 VALUES IN (2020,2022,2024,2026),
 SUBPARTITION sp1 VALUES IN (2021,2023,2025,2027)
);

CREATE TABLE `k_l_tp_t2` (
`a` bigint(20) UNSIGNED NOT NULL,
`b` bigint(20) UNSIGNED NOT NULL,
`c` datetime NOT NULL,
`d` varchar(16) NOT NULL,
`e` varchar(16) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`) PARTITIONS 2 
SUBPARTITION BY LIST(YEAR(`c`)) 
(
 SUBPARTITION sp0 VALUES IN (2020,2022,2024,2026),
 SUBPARTITION sp1 VALUES IN (2021,2023,2025,2027)
);

示例1:修改模板化二级List分区并增加Values

给k_l_tp_t1表的二级分区模板sp1增加2个values,新的values值是(2017,2019)。具体用法如下所示:

表级用法

## 基于表名字进行表级的分区变更操作
ALTER TABLE k_l_tp_t1 /*表名*/ 
	MODIFY SUBPARTITION sp1 /*二级分区模板名字*/ ADD VALUES (2017,2019);
表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即上述两个表同时执行分区变更:

## 基于表组名字进行表组级的分区变更操作, 假设表组名是tg1
ALTER TABLEGROUP tg1 /*表组名*/ 
	MODIFY SUBPARTITION sp1 /*二级分区模板名字*/ ADD VALUES (2017,2019);

## 基于表名进行表组级的分区变更操作(即基于表名自动找查对应的表组并进行操作)
ALTER TABLEGROUP BY TABLE k_l_tp_t1 /*表名*/ 
	MODIFY SUBPARTITION sp1 /*二级分区模板名字*/ ADD VALUES (2017,2019);

示例2:修改模板化二级List分区并删除Values

给k_l_tp_t1表的二级分区模板sp1删除两个values,这两个values是2021与2025。具体用法如下所示:

表级用法

## 基于表名字进行表级的分区变更操作
ALTER TABLE k_l_tp_t1 /*表名*/ 
	MODIFY SUBPARTITION sp1 /*二级分区模板名字*/ DROP VALUES (2021,2025);

表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即上述两个表同时执行分区变更:

## 基于表组名字进行表组级的分区变更操作
ALTER TABLEGROUP tg1 /*表组名*/ 
	MODIFY SUBPARTITION sp1 /*二级分区模板名字*/ DROP VALUES (2021,2025);

## 基于表名进行表组级的分区变更操作(即基于表名自动找查对应的表组并进行操作)
ALTER TABLEGROUP BY TABLE k_l_tp_t1 /*表名*/ 
	MODIFY SUBPARTITION sp1 /*二级分区模板名字*/ DROP VALUES (2021,2025);

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

k_l_ntp_t1与k_l_ntp_t2都采用Key+List的二级分区,建表SQL如下所示:

CREATE TABLE `k_l_ntp_t1` (
`a` bigint(20) UNSIGNED NOT NULL,
`b` bigint(20) UNSIGNED NOT NULL,
`c` datetime NOT NULL,
`d` varchar(16) NOT NULL,
`e` varchar(16) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`) PARTITIONS 2
SUBPARTITION BY LIST(YEAR(`c`))
(
 PARTITION p1 (
 	SUBPARTITION p1sp1 VALUES IN (2020,2022,2024,2026,2028),
 	SUBPARTITION p1sp2 VALUES IN (2021,2023,2025,2027,2029)
	),
 PARTITION p2 (
 	SUBPARTITION p2sp1 VALUES IN (2020,2022,2024,2026,2028),
 	SUBPARTITION p2sp2 VALUES IN (2021,2023,2025,2027,2029),
 	SUBPARTITION p2sp3 VALUES IN (2030,2031)
	)
);

CREATE TABLE `k_l_ntp_t2` (
`a` bigint(20) UNSIGNED NOT NULL,
`b` bigint(20) UNSIGNED NOT NULL,
`c` datetime NOT NULL,
`d` varchar(16) NOT NULL,
`e` varchar(16) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`) PARTITIONS 2
SUBPARTITION BY LIST(YEAR(`c`))
(
 PARTITION p1 (
 	SUBPARTITION p1sp1 VALUES IN (2020,2022,2024,2026,2028),
 	SUBPARTITION p1sp2 VALUES IN (2021,2023,2025,2027,2029)
	),
 PARTITION p2 (
 	SUBPARTITION p2sp1 VALUES IN (2020,2022,2024,2026,2028),
 	SUBPARTITION p2sp2 VALUES IN (2021,2023,2025,2027,2029),
 	SUBPARTITION p2sp3 VALUES IN (2030,2031)
	)
);

示例1:修改非模板化二级List分区并增加Values

给k_l_ntp_t1表的第1个一级分区p1的二级分区p1sp2增加2个values,新的values值是(2017,2019)。具体用法如下所示:

表级用法

## 基于表名字进行表级的分区变更操作
ALTER TABLE k_l_ntp_t1 /*表名*/ 
	MODIFY SUBPARTITION p1sp2 ADD VALUES (2017,2019);

表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即上述两个表同时执行分区变更:

## 基于表组名字进行表组级的分区变更操作, 假设表组名是tg1
ALTER TABLEGROUP tg1 /*表组名*/ 
	MODIFY SUBPARTITION p1sp2 /*实际的非模板化二级分区的名字*/ ADD VALUES (2017,2019);

## 基于表名进行表组级的分区变更操作(即基于表名自动找查对应的表组并进行操作)
ALTER TABLEGROUP BY TABLE k_l_ntp_t1 /*表名*/ 
	MODIFY SUBPARTITION p1sp2 /*实际的非模板化二级分区的名字*/ ADD VALUES (2017,2019);

示例2:修改非模板化二级List分区并删除Values

给k_l_tp_t1表的一级分区p1下的二级分区p1sp1删除两个values,这两个values是2021与2025。具体用法如下所示:

表级用法

## 基于表名字进行表级的分区变更操作
ALTER TABLE k_l_tp_t1 /*表名*/ 
	MODIFY SUBPARTITION p1sp2 /*实际的非模板化二级分区的名字*/ DROP VALUES (2021,2025);

表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即上述两个表同时执行分区变更:

## 基于表组名字进行表组级的分区变更操作
ALTER TABLEGROUP tg1 /*表组名*/ 
	MODIFY SUBPARTITION p1sp2 DROP VALUES (2021,2025);

## 基于表名进行表组级的分区变更操作(即基于表名自动找查对应的表组并进行操作)
ALTER TABLEGROUP BY TABLE k_l_ntp_t1 /*表名*/ 
	MODIFY SUBPARTITION p1sp2 /*实际的非模板化二级分区的名字*/ DROP VALUES (2021,2025);

场景4:目标分区是全局索引表的分区

示例1:给指定的全局索引表的指定的一级LIST分区增加Values

r_gl_t1是一个使用全局索引的表, 全局索引g_l使用了LIST进行分区,建表SQL如下所示:

CREATE TABLE `r_gl_t1` (
	`a` bigint(20) UNSIGNED NOT NULL,
	`b` bigint(20) UNSIGNED NOT NULL,
	`c` datetime NOT NULL,
	`d` varchar(16) NOT NULL,
	`e` varchar(16) NOT NULL,
	GLOBAL INDEX `g_l` (`a`) COVERING (`c`)
		PARTITION BY LIST(`a`) (
 PARTITION `p0` VALUES IN (10000,10002,10004,10006,10008),
		 PARTITION `p1` VALUES IN (20000,20001,20002,20003,20004),
 PARTITION `p2` VALUES IN (30000,30001,30002)
 )
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY RANGE(YEAR(`c`))
(PARTITION `p0` VALUES LESS THAN (2020),
 PARTITION `p1` VALUES LESS THAN (2021));

CREATE TABLE `r_gl_t2` (
	`a` bigint(20) UNSIGNED NOT NULL,
	`b` bigint(20) UNSIGNED NOT NULL,
	`c` datetime NOT NULL,
	`d` varchar(16) NOT NULL,
	`e` varchar(16) NOT NULL,
	GLOBAL INDEX `g_l` (`a`) COVERING (`c`)
		PARTITION BY LIST(`a`) (
 PARTITION `p0` VALUES IN (10000,10002,10004,10006,10008),
		 PARTITION `p1` VALUES IN (20000,20001,20002,20003,20004),
 PARTITION `p2` VALUES IN (30000,30001,30002)
 )
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY RANGE(YEAR(`c`))
(PARTITION `p0` VALUES LESS THAN (2020),
 PARTITION `p1` VALUES LESS THAN (2021));

给r_gl_t1表的全局索引g_r的一级分区p2增加两个新values,新values是(30003,30004)。具体用法如下所示:

表级用法

## 基于 `表名`.`全局索引名` 进行全局索引表的分区变更操作
ALTER TABLE `r_gl_t1`.`g_l`
 MODIFY PARTITION p2 ADD VALUES (30003,30004);

## 基于 `全局索引` ON TALBE `表名` 进行全局索引表的分区变更操作
ALTER INDEX `g_l`/*全局索引名*/ ON TABLE `r_gl_t1` /*表名*/
 MODIFY PARTITION p2 ADD VALUES (30003,30004);

表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即上述两个表同时执行分区变更。例如让r_gl_t1表的全局索引g_l与r_gl_t2表的全局索引g_l都同时发生变更:

## 基于表组名字进行表组级的分区变更操作,假如全局索引表的表组名是tg1
ALTER TABLEGROUP tg1 /*表组名*/ 
 MODIFY PARTITION sp2 ADD VALUES (30003,30004);;

## 基于 `全局索引` ON TALBE `表名` 进行全局索引表的表组的分区变更操作
ALTER TABLEGROUP BY INDEX `g_l`/*全局索引名*/ ON TABLE `r_gl_t1` /*表名*/
 MODIFY PARTITION p2 ADD VALUES (30003,30004);

示例2:给指定的全局索引表的指定的二级LIST分区增加Values

r_g_kl_t1是一个使用全局索引的分区表,其中全局索引使用Key+List的二级分区,建表SQL如下所示:

CREATE TABLE `r_g_kl_t1` (
	`a` bigint(20) UNSIGNED NOT NULL,
	`b` bigint(20) UNSIGNED NOT NULL,
	`c` datetime NOT NULL,
	`d` varchar(16) NOT NULL,
	`e` varchar(16) NOT NULL,
	GLOBAL INDEX `g_kl` (`a`,`b`) COVERING (`c`)
		PARTITION BY KEY(`b`) PARTITIONS 2
 	SUBPARTITION BY LIST(`a`)
		(
 SUBPARTITION `sp0` VALUES IN (10000,10002,10004,10006,10008),
		 SUBPARTITION `sp1` VALUES IN (20000,20001,20002,20003,20004),
 SUBPARTITION `sp2` VALUES IN (30000,30001,30002)
 )
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY RANGE(YEAR(`c`))
(PARTITION `p0` VALUES LESS THAN (2020),
 PARTITION `p1` VALUES LESS THAN (2021));
 
CREATE TABLE `r_g_kl_t2` (
	`a` bigint(20) UNSIGNED NOT NULL,
	`b` bigint(20) UNSIGNED NOT NULL,
	`c` datetime NOT NULL,
	`d` varchar(16) NOT NULL,
	`e` varchar(16) NOT NULL,
	GLOBAL INDEX `g_kl` (`a`,`b`) COVERING (`c`)
		PARTITION BY KEY(`b`) PARTITIONS 2
 	SUBPARTITION BY LIST(`a`)
		(
 SUBPARTITION `sp0` VALUES IN (10000,10002,10004,10006,10008),
		 SUBPARTITION `sp1` VALUES IN (20000,20001,20002,20003,20004),
 SUBPARTITION `sp2` VALUES IN (30000,30001,30002)
 )
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY RANGE(YEAR(`c`))
(PARTITION `p0` VALUES LESS THAN (2020),
 PARTITION `p1` VALUES LESS THAN (2021));

给r_g_kl_t1表的全局索引g_kl的二级分区模板sp2增加新的values,新的values是 (30003, 30004)。具体用法如下所示:

表级用法

## 基于 `表名`.`全局索引名` 进行全局索引表的分区变更操作
ALTER TABLE `r_g_kl_t1`.`g_kl`
 MODIFY SUBPARTITION sp2 ADD VALUES (30003,30004);

## 基于 `全局索引` ON TALBE `表名` 进行全局索引表的分区变更操作
ALTER INDEX g_kl/*全局索引名*/ ON TABLE `r_g_kl_t1` /*表名*/
 MODIFY SUBPARTITION sp2 ADD VALUES (30003,30004);

表组级用法

同一个表组的所有逻辑表同时进行增加分区的操作,即修改全局索引所对应的表组的分区定义。例如让 r_g_kl_t1表的全局索引g_kl与r_g_kl_t2表的全局索引g_kl都同时发生变更:

## 基于表组名字进行表组级的分区变更操作,假如全局索引表的表组名是tg1
ALTER TABLEGROUP tg1 /*表组名*/ 
 MODIFY SUBPARTITION sp2 ADD VALUES (30003,30004);

## 基于 INDEX `全局索引` ON TALBE `表名` 进行全局索引表的表组的分区变更操作
ALTER TABLEGROUP BY INDEX `g_kl`/*全局索引名*/ ON TABLE `r_g_kl_t1` /*表名*/
 MODIFY SUBPARTITION sp2 ADD VALUES (30003,30004);