临时分区

什么是临时分区

某些情况下,用户希望对分区的范围进行修改,比如合并两个分区,或将一个大分区分割成多个小分区。则用户可以先建立对应合并或分割后范围的临时分区,然后通过 INSERT INTO 命令将正式分区的数据导入到临时分区中,通过替换操作,原子的替换原有分区,以达到目的。

应用场景

  1. 原子的覆盖写操作

某些情况下,用户希望能够重写某一分区的数据,但如果采用先删除再导入的方式进行,在中间会有一段时间无法查看数据。这时,用户可以先创建一个对应的临时分区,将新的数据导入到临时分区后,通过替换操作,原子的替换原有分区,以达到目的。对于非分区表的原子覆盖写操作,请参阅表替换文档

  1. 修改分桶数

某些情况下,用户在创建分区时使用了不合适的分桶数。则用户可以先创建一个对应分区范围的临时分区,并指定新的分桶数。然后通过 INSERT INTO 命令将正式分区的数据导入到临时分区中,通过替换操作,原子的替换原有分区,以达到目的。

  1. 合并或分割分区

某些情况下,用户希望对分区的范围进行修改,比如合并两个分区,或将一个大分区分割成多个小分区。则用户可以先建立对应合并或分割后范围的临时分区,然后通过 INSERT INTO 命令将正式分区的数据导入到临时分区中,通过替换操作,原子的替换原有分区,以达到目的。

如何使用临时分区

创建临时分区

通过 ALTER TABLE ADD TEMPORARY PARTITION 语句可以创建临时分区。

示例

ALTER TABLE tbl1 ADD TEMPORARY PARTITION tp1 VALUES LESS THAN("2020-02-01");

ALTER TABLE tbl2 ADD TEMPORARY PARTITION tp1 VALUES [("2020-01-01"), ("2020-02-01"));

ALTER TABLE tbl1 ADD TEMPORARY PARTITION tp1 VALUES LESS THAN("2020-02-01")
("in_memory" = "true", "replication_num" = "1")
DISTRIBUTED BY HASH(k1) BUCKETS 5;

ALTER TABLE tbl3 ADD TEMPORARY PARTITION tp1 VALUES IN ("Beijing", "Shanghai");

ALTER TABLE tbl4 ADD TEMPORARY PARTITION tp1 VALUES IN ((1, "Beijing"), (1, "Shanghai"));

ALTER TABLE tbl3 ADD TEMPORARY PARTITION tp1 VALUES IN ("Beijing", "Shanghai")
("in_memory" = "true", "replication_num" = "1")
DISTRIBUTED BY HASH(k1) BUCKETS 5;

注意事项

  • 临时分区的添加和正式分区的添加操作相似。临时分区的分区范围独立于正式分区。
  • 临时分区可以独立指定一些属性。包括分桶数、副本数、是否是内存表、存储介质等信息。

导入数据至临时分区

INSERT INTO 导入

INSERT INTO table_name TEMPORARY PARTITION(tp_name, ) SELECT (sql_statment)

STREAM LOAD 导入

curl --location-trusted -u root: -H "label:123" -H "temporary_partitions: tp1, tp2, ..." -T testData \
    http://host:port/api/testDb/testTbl/_stream_load    

BROKER LOAD 导入

LOAD LABEL example_db.label1
(
    DATA INFILE("hdfs://hdfs_host:hdfs_port/user/starrocks/data/input/file")
    INTO TABLE `my_table`
    TEMPORARY PARTITION (tp1, tp2, ...)
    ...
)
WITH BROKER hdfs ("username"="hdfs_user", "password"="hdfs_password");

ROUTINE LOAD 导入

CREATE ROUTINE LOAD example_db.test1 ON example_tbl
COLUMNS(k1, k2, k3, v1, v2, v3 = k1 * 100),
TEMPORARY PARTITIONS(tp1, tp2, ...),
WHERE k1 > 100
PROPERTIES
("property_type"="property_value" ,...)
FROM KAFKA
(property_desc);

查询临时分区

查询指定的临时分区

SELECT column_name FROM
table_name TEMPORARY PARTITION(tp1, tp2, ...) ;

SELECT column_name FROM
table_name TEMPORARY PARTITION(tp1, tp2, ...)
JOIN
table_name TEMPORARY PARTITION(tp1, tp2, ...)
ON ...
WHERE ...;

使用临时分区进行替换

通过 ALTER TABLE REPLACE PARTITION 语句可以将一个表的正式分区替换为临时分区。

示例

ALTER TABLE tbl1 REPLACE PARTITION (p1) WITH TEMPORARY PARTITION (tp1);

ALTER TABLE tbl1 REPLACE PARTITION (p1, p2) WITH TEMPORARY PARTITION (tp1, tp2, tp3);

ALTER TABLE tbl1 REPLACE PARTITION (p1, p2) WITH TEMPORARY PARTITION (tp1, tp2)
PROPERTIES (
    "strict_range" = "false",
    "use_temp_partition_name" = "true"
);

参数说明

  • strict_range

    默认为 true。

    对于 Range 分区,当该参数为 true 时,表示要被替换的所有正式分区的范围并集需要和替换的临时分区的范围并集完全相同。当置为 false 时,只需要保证替换后,新的正式分区间的范围不重叠即可。

    示例1 待替换的分区 p1, p2, p3 的范围 (=> 并集):

    [10, 20), [20, 30), [40, 50) => [10, 30), [40, 50)

    替换分区 tp1, tp2 的范围(=> 并集):

    [10, 30), [40, 45), [45, 50) => [10, 30), [40, 50)

    范围并集相同,则可以使用 tp1 和 tp2 替换 p1, p2, p3。

    示例2 待替换的分区 p1 的范围 (=> 并集):

    [10, 50) => [10, 50)

    替换分区 tp1, tp2 的范围(=> 并集):

    [10, 30), [40, 50) => [10, 30), [40, 50)

    范围并集不相同,如果 strict_range 为 true,则不可以使用 tp1 和 tp2 替换 p1。如果为 false,且替换后的两个分区范围 [10, 30), [40, 50) 和其他正式分区不重叠,则可以替换。

    示例3 待替换的分区 p1, p2 的枚举值(=> 并集):

    (1, 2, 3), (4, 5, 6) => (1, 2, 3, 4, 5, 6)

    替换分区 tp1, tp2, tp3 的枚举值(=> 并集):

    (1, 2, 3), (4), (5, 6) => (1, 2, 3, 4, 5, 6)

    枚举值并集相同,可以使用 tp1,tp2,tp3 替换 p1,p2。

    示例4 待替换的分区 p1, p2,p3 的枚举值(=> 并集):

    (("1","beijing"), ("1", "shanghai")), (("2","beijing"), ("2", "shanghai")), (("3","beijing"), ("3", "shanghai")) => (("1","beijing"), ("1", "shanghai"), ("2","beijing"), ("2", "shanghai"), ("3","beijing"), ("3", "shanghai"))

    替换分区 tp1, tp2 的枚举值(=> 并集):

    (("1","beijing"), ("1", "shanghai")), (("2","beijing"), ("2", "shanghai"), ("3","beijing"), ("3", "shanghai")) => (("1","beijing"), ("1", "shanghai"), ("2","beijing"), ("2", "shanghai"), ("3","beijing"), ("3", "shanghai"))

    枚举值并集相同,可以使用 tp1,tp2 替换 p1,p2,p3。

  • use_temp_partition_name

    默认为 false。当该参数为 false,并且待替换的分区和替换分区的个数相同时,则替换后的正式分区名称维持不变。

    如果为 true,则替换后,正式分区的名称为替换分区的名称。

    示例 1

    ALTER TABLE tbl1 REPLACE PARTITION (p1) WITH TEMPORARY PARTITION (tp1);

    use_temp_partition_name 默认为 false,则在替换后,分区的名称依然为 p1,但是相关的数据和属性都替换为 tp1 的。

    如果 use_temp_partition_name 默认为 true,则在替换后,分区的名称为 tp1。p1 分区不再存在。

    示例 2

    ALTER TABLE tbl1 REPLACE PARTITION (p1, p2) WITH TEMPORARY PARTITION (tp1);

    use_temp_partition_name 默认为 false,但因为待替换分区的个数和替换分区的个数不同,则该参数无效。替换后,分区名称为 tp1,p1 和 p2 不再存在。

注意事项

  1. 分区替换成功后,被替换的分区将被删除且不可恢复。

  2. 当表存在临时分区时,无法使用 Alter 命令对表进行 Schema Change 等变更操作。

  3. 当表在进行变更操作时,无法对表添加临时分区。

删除临时分区

通过 ALTER TABLE DROP TEMPORARY PARTITION 语句可以将一个表的临时分区删除。

示例

ALTER TABLE tbl1 DROP TEMPORARY PARTITION tp1;

注意事项

与 DROP 相关

  1. 使用 Drop 操作直接删除数据库或表后,可以通过 Recover 命令恢复数据库或表(限定时间内),但临时分区不会被恢复。

  2. 使用 Alter 命令删除正式分区后,可以通过 Recover 命令恢复分区(限定时间内)。临时分区与正式分区是无关联的两部分,操作临时分区不会对正式分区产生影响。

  3. 使用 Alter 命令删除临时分区后,无法通过 Recover 命令恢复临时分区。

与 TRUNCATE 相关

  1. 使用 Truncate 命令清空表,表的临时分区会被删除,且不可恢复。

  2. 使用 Truncate 命令清空正式分区时,不影响临时分区。

  3. 不可使用 Truncate 命令清空临时分区。