1. 背景
OceanBase数据库支持hash、range、list等多种类型的分区表以及二级分区,使得OceanBase数据库具备强大的可扩展性。分区表的分区名可以由用户指定或者按照一定的命名规则由系统自动生成,用户业务场景中,存在修改分区名的需求。
在OceanBase数据库中,要修改分区名,需要重建分区表并进行数据迁移,操作繁琐且性能较差。在Oracle数据库中,分区表重命名功能只需要一条简单的SQL即可实现。所以,OceanBase 4.2.1 版本兼容了Oracle数据库的分区表重命名功能,提升分区表易用性。
2. 分区重命名
2.1. 语法说明
OceanBase数据库从 4.2.1 版本开始支持通过alter table rename的方式进行分区重命名,具体语法如下所示:
ALTER TABLE table_name RENAME { PARTITION | SUBPARITION } partition_name TO new_name
字段说明
字段名称 | 描述 |
table_name | 指定要重命名分区的分区表名称。 |
partition | 指定要修改分区表的一级分区。 |
subpartition | 指定要修改分区表的二级分区。 |
partition_name | 指定要修改分区的分区名。 |
new_name | 指定要修改分区的新分区名。 |
可见性
分区重命名操作会修改主表的相关分区,但是不会影响到局部索引的分区名。在完成该操作后,可以在与主表分区相关的视图如USER_TAB_PARTITIONS,USER_TAB_SUBPARTITIONS确认分区名修改后的结果。
2.2. 功能实践
下面以range类型的二级分区表为例,展示分区重命名功能的实际操作及效果。
CREATE TABLE range_range_table(col1 INT, col2 INT, col3 INT)
PARTITION BY RANGE(col1)
SUBPARTITION BY RANGE(col2)
(PARTITION p0 VALUES LESS THAN(100)
(SUBPARTITION sp0 VALUES LESS THAN(100),
SUBPARTITION sp1 VALUES LESS THAN(200)
),
PARTITION p1 VALUES LESS THAN(200)
(SUBPARTITION sp2 VALUES LESS THAN(100),
SUBPARTITION sp3 VALUES LESS THAN(200),
SUBPARTITION sp4 VALUES LESS THAN(300)
)
);
CREATE INDEX local_idx_for_range_range_tb on range_range_table (col1) local;
场景1. 修改一级分区名
1.查看分区名
SELECT partition_name FROM SYS.USER_TAB_PARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE';
+----------------+
| PARTITION_NAME |
+----------------+
| P0 |
| P1 |
+----------------+
2.重命名一级分区p0
ALTER TABLE range_range_table RENAME PARTITION p0 TO p10;
3.查看分区名
SELECT partition_name FROM SYS.USER_TAB_PARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE';
+----------------+
| PARTITION_NAME |
+----------------+
| P10 |
| P1 |
+----------------+
场景2. 修改二级分区名
1.查看分区名
SELECT partition_name, subpartition_name FROM SYS.USER_TAB_SUBPARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE';
+----------------+-------------------+
| PARTITION_NAME | SUBPARTITION_NAME |
+----------------+-------------------+
| P0 | SP1 |
| P0 | SP0 |
| P1 | SP4 |
| P1 | SP3 |
| P1 | SP2 |
+----------------+-------------------+
2.重命名二级分区sp0
ALTER TABLE range_range_table RENAME SUBPARTITION sp0 TO sp10;
3.查看新分区名
SELECT partition_name, subpartition_name FROM SYS.USER_TAB_SUBPARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE';
+----------------+-------------------+
| PARTITION_NAME | SUBPARTITION_NAME |
+----------------+-------------------+
| P0 | SP1 |
| P0 | SP10 |
| P1 | SP4 |
| P1 | SP3 |
| P1 | SP2 |
+----------------+-------------------+
场景3. 修改分区名与已有分区名冲突时会报错
ALTER TABLE range_range_table RENAME PARTITION p0 TO p1;
ORA-14082: New partition name P1 must differ from that of any other partition or subpartition of the object.
ALTER TABLE range_range_table RENAME SUBPARTITION sp0 TO sp1;
ORA-14263: New subpartition name SP1 must differ from that of any other partition or subpartition of the object.
场景4. 修改分区的分区名不存在时报错
ALTER TABLE range_range_table RENAME PARTITION p10 TO p100;
ORA-02149: Specified partition does not exist
ALTER TABLE range_range_table RENAME SUBPARTITION sp11 TO sp111;
ORA-14251: Specified subpartition does not exist
2.3. 使用限制
- 分区重命名过程中,如果与持有相关分区锁资源的DML产生冲突会阻塞分区名修改操作,直到DML释放相关分区锁资源。
- 由于Oracle对于分区名的辨别是大小写敏感的,而OB对于分区名的辨别是大小写不敏感的。因此在Oracle中,可以将分区重命名为大小写不同的分区名,而在OB中进行该操作会报错分区名已存在。
ALTER TABLE range_range_table RENAME PARTITION p0 to "p0";
ORA-14082: New partition name p0 must differ from that of any other partition or subpartition of the object.
- 分区重命名只修改主表分区名,不会修改主表所属局部索引的分区名。分区重命名后进行drop column等会重建局部索引的行为时,局部索引的分区名会变为跟主表分区名一致。
1.查看分区名
SELECT partition_name, subpartition_name FROM SYS.USER_TAB_SUBPARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE';
+----------------+-------------------+
| PARTITION_NAME | SUBPARTITION_NAME |
+----------------+-------------------+
| P0 | SP1 |
| P0 | SP0 |
| P1 | SP4 |
| P1 | SP3 |
| P1 | SP2 |
+----------------+-------------------+
2.重命名一级分区p0和二级分区sp0
ALTER TABLE range_range_table RENAME PARTITION p0 TO p10;
ALTER TABLE range_range_table RENAME SUBPARTITION sp0 TO sp10;
3.查看主表新分区名
SELECT partition_name, subpartition_name FROM SYS.USER_TAB_SUBPARTITIONS WHERE table_name = 'RANGE_RANGE_TABLE';
+----------------+-------------------+
| PARTITION_NAME | SUBPARTITION_NAME |
+----------------+-------------------+
| P10 | SP1 |
| P10 | SP10 |
| P1 | SP4 |
| P1 | SP3 |
| P1 | SP2 |
+----------------+-------------------+
4.查看局部索引分区名
SELECT partition_name, subpartition_name FROM SYS.USER_IND_SUBPARTITIONS WHERE index_name = 'LOCAL_IDX_FOR_RANGE_RANGE_TB';
+----------------+-------------------+
| PARTITION_NAME | SUBPARTITION_NAME |
+----------------+-------------------+
| P0 | SP1 |
| P0 | SP0 |
| P1 | SP4 |
| P1 | SP3 |
| P1 | SP2 |
+----------------+-------------------+
5.删列触发数据重整
ALTER TABLE range_range_table DROP COLUMN col3;
6.查看局部索引分区名
SELECT partition_name, subpartition_name FROM SYS.USER_IND_SUBPARTITIONS WHERE index_name = 'LOCAL_IDX_FOR_RANGE_RANGE_TB';
+----------------+-------------------+
| PARTITION_NAME | SUBPARTITION_NAME |
+----------------+-------------------+
| P10 | SP1 |
| P10 | SP10 |
| P1 | SP4 |
| P1 | SP3 |
| P1 | SP2 |
+----------------+-------------------+
- mysql租户暂不支持该功能。