模板化创建的hash+range分区是否可以批量删除二级分区

【 使用环境 】生产环境
【 OB or 其他组件 】OBserver
【 使用版本 】4.2.1 BP10
【问题描述】hash+range 创建二级分区表(通过二级分区模板SUBPARTITION TEMPLATE),如何批量删除所有一级分区下同名的二级子分区。

该表从分库分表模式迁入OB,表结构示例如下:
CREATE TABLE T_test (
ID bigint(20) NOT NULL ,
Options bigint(20) NOT NULL DEFAULT ‘0’ ,
Type smallint(6) NOT NULL ,
part_Sharding bigint(20) NOT NULL ,
CreateTime bigint(20) NOT NULL
PRIMARY KEY (ID, part_Sharding, CreateTime),
) DEFAULT CHARSET=utf8mb4 TABLEGROUP = tg_mutil
PARTITION BY HASH(part_Sharding)
SUBPARTITION BY RANGE (CreateTime)
SUBPARTITION TEMPLATE
(SUBPARTITION p20250109 values less than (1736352000000),
SUBPARTITION p20250116 values less than (1736956800000),
SUBPARTITION p20250123 values less than (1737561600000),
SUBPARTITION p20250130 values less than (1738166400000),
SUBPARTITION p20250206 values less than (1738771200000),
SUBPARTITION p20250213 values less than (1739376000000),
SUBPARTITION p20250220 values less than (1739980800000),
SUBPARTITION p20250227 values less than (1740585600000),
SUBPARTITION p20250306 values less than (1741190400000),
SUBPARTITION p20250313 values less than (1741795200000),
SUBPARTITION p20250320 values less THAN MAXVALUE)PARTITIONS 300;

是否有方案批量删除300个hash一级分区下所有的二级分区p20250109 ,一个SQL执行所有同名二级分区的删除?

【复现路径】
【附件及日志】

– 创建存储过程
DELIMITER //
CREATE PROCEDURE delete_subpartition_batch()
BEGIN
– 声明变量
DECLARE v_partition_name VARCHAR(255);
DECLARE v_done INT DEFAULT 0;
DECLARE cur_partition CURSOR FOR
– 查询所有一级分区的名称
SELECT partition_name
FROM information_schema.partitions
WHERE table_name = ‘T_test’
AND subpartition_name IS NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = 1;

-- 打开游标
OPEN cur_partition;

-- 循环遍历一级分区
partition_loop: LOOP
    -- 从游标中获取一级分区名称
    FETCH cur_partition INTO v_partition_name;
    IF v_done THEN
        LEAVE partition_loop;
    END IF;

    -- 构造删除指定二级分区的 SQL 语句
    SET @delete_sql = CONCAT('ALTER TABLE T_test DROP PARTITION ', v_partition_name, 'p20250109');

    -- 准备并执行动态 SQL
    PREPARE stmt FROM @delete_sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END LOOP;

-- 关闭游标
CLOSE cur_partition;

END //
DELIMITER ;

– 调用存储过程
CALL delete_subpartition_batch();

感谢提供,本意是想通过一个SQL直接删除 同名二级分区,目前应该是还没有这个功能

@论坛小助手

根据文档库中的信息,回答如下:

1. 关于 HASH + RANGE 分区表的二级分区删除支持情况

根据文档片段 7 和 8 的内容,HASH + RANGE 的二级分区表在 OceanBase 数据库中属于以下类型:

  • 一级分区类型HASH
  • 二级分区类型RANGE

从文档片段 7 的表格中可以看到:

  • 对于 HASH + RANGE 的二级分区表,添加一级分区添加二级分区均不支持。
  • 这意味着该类型的二级分区表在创建后,其分区结构是固定的,无法动态新增或删除分区。

因此,HASH + RANGE 的二级分区表在 OceanBase 数据库中不支持删除二级分区,无论是单个还是批量删除。


2. 是否有批量删除同名二级分区的方案

目前,OceanBase 数据库的 SQL 语法中没有提供直接批量删除同名二级分区的功能。即使通过循环或其他方式模拟批量操作,也无法绕过上述限制,因为 HASH + RANGE 的二级分区表本身就不支持删除分区。


3. 解决方案建议

如果需要清理特定的二级分区数据,可以考虑以下替代方案:

(1) 使用 TRUNCATE PARTITION 清空二级分区数据

虽然无法删除二级分区,但可以通过 TRUNCATE PARTITIONTRUNCATE SUBPARTITION 清空二级分区中的数据。例如:

ALTER TABLE T_test TRUNCATE SUBPARTITION p20250109;

此操作会清空指定二级分区的数据,但保留分区结构。

如果需要批量清空所有一级分区下的同名二级分区(如 p20250109),可以通过动态 SQL 实现。例如:

SET @table_name = 'T_test';
SET @subpartition_name = 'p20250109';

SELECT CONCAT('ALTER TABLE ', @table_name, ' TRUNCATE SUBPARTITION ', @subpartition_name, ';') 
FROM INFORMATION_SCHEMA.PARTITIONS 
WHERE TABLE_NAME = @table_name AND SUBPARTITION_NAME = @subpartition_name;

-- 将生成的 SQL 执行即可

(2) 重建表以移除不需要的二级分区

如果需要彻底移除某些二级分区,可以考虑重建表。具体步骤如下:

  1. 创建一个新表,定义所需的分区结构(排除不需要的二级分区)。
  2. 使用 INSERT INTO ... SELECT 将原表数据迁移到新表。
  3. 替换原表为新表。

示例:

CREATE TABLE T_test_new (
    ID bigint(20) NOT NULL,
    Options bigint(20) NOT NULL DEFAULT '0',
    Type smallint(6) NOT NULL,
    part_Sharding bigint(20) NOT NULL,
    CreateTime bigint(20) NOT NULL,
    PRIMARY KEY (ID, part_Sharding, CreateTime)
) DEFAULT CHARSET=utf8mb4 TABLEGROUP = tg_mutil
PARTITION BY HASH(part_Sharding)
SUBPARTITION BY RANGE (CreateTime)
SUBPARTITION TEMPLATE (
    SUBPARTITION p20250116 values less than (1736956800000),
    SUBPARTITION p20250123 values less than (1737561600000),
    -- 其他需要保留的二级分区
) PARTITIONS 300;

INSERT INTO T_test_new SELECT * FROM T_test;

RENAME TABLE T_test TO T_test_old, T_test_new TO T_test;
DROP TABLE T_test_old;

4. 总结

  • 问题原因HASH + RANGE 的二级分区表在 OceanBase 数据库中不支持删除二级分区。
  • 解决方案:可以通过 TRUNCATE SUBPARTITION 清空数据,或者重建表以移除不需要的二级分区。
  • 建议:如果频繁需要调整分区结构,建议重新评估分区设计,尽量避免使用固定分区模板(SUBPARTITION TEMPLATE),以便更灵活地管理分区。

希望以上解答对您有所帮助!

详情请参考:

  1. DROP TABLE
  2. 使用 OceanBase 数据库分区表进行水平拆分
  3. OceanBase 术语
  4. DROP OUTLINE
  5. 添加分区
  6. 创建分区表