Doris临时分区

临时分区

临时分区是归属于某一分区表的。只有分区表可以创建临时分区。这块很核心只有分区表才会有临时分区。

规则:
临时分区的分区字段和正式分区一样
临时分区的名称必须不一样并且和正式分区也不一样
临时分区支持添加、删除、替换操作
临时分区的添加和正式分区的添加操作相似。临时分区的分区范围独立于正式分区。

添加临时分区
ALTER TABLE expamle_range_tbl ADD TEMPORARY PARTITION tp2 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 expamle_range_tbl DROP TEMPORARY PARTITION tp1;

插入临时分区测试数据;
此处注意插入时若不指定临时分区,则默认插入正式分区,若数据不在正式分区范围内,则会报错;如下就是正常插入时数据不落入任何分区时会报错。

以下插入指定临时分区时,所对应的数据必须能放入临时分区的范围,否则会报无法匹配的错误 如下: Reason: no partition for this tuple. tuple=(11111 2022-04-01 2000-11-11 11:11:11 bj 111 1 2022-01-01 00:00:00 1000 11 22). src line: [];

INSERT INTO expamle_range_tbl TEMPORARY PARTITION(tp2) values(11111,'2018-04-01','2000-11-11 11:11:11','bj',111,1,'2022-01-01 00:00:00',1000,11,22);


INSERT INTO expamle_range_tbl TEMPORARY PARTITION(tp2) values(11111,'2022-04-01','2000-11-11 11:11:11','bj',111,1,'2022-01-01 00:00:00',1000,11,22);

查询临时分区数据

SELECT ... FROM
tbl1 TEMPORARY PARTITION(tp1, tp2, ...)
JOIN
tbl2 TEMPORARY PARTITION(tp1, tp2, ...)
ON ...
WHERE ...;

select * from expamle_range_tbl TEMPORARY PARTITION(tp2);

如上查询则就查询到插入临时分区的数据

替换分区

可以通过 ALTER TABLE REPLACE PARTITION 语句将一个表的正式分区替换为临时分区。
strict_range :
默认为 true。当该参数为 true 时,表示要被替换的所有正式分区的范围并集需要和替换的临时分区的范围并集完全相同。当置为 false 时,只需要保证替换后,新的正式分区间的范围不重叠即可。
具体使用见官网例子:

use_temp_partition_name:
默认为 false。当该参数为 false,并且待替换的分区和替换分区的个数相同时,则替换后的正式分区名称维持不变。如果为 true,则替换后,正式分区的名称为替换分区的名称。
分区替换成功后,被替换的分区将被删除且不可恢复 : 也就是被替换的分区将被删除掉不可以恢复

--  以下这个语句的作用是使用 tp1 分区替换 p1 分区
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"
);

实操:

-- 创建表
CREATE TABLE `expamle_range_tbl` (
  `user_id` largeint(40) NOT NULL COMMENT "用户id",
  `date` date NOT NULL COMMENT "数据灌入日期时间",
  `timestamp` datetime NOT NULL COMMENT "数据灌入的时间戳",
  `city` varchar(20) NULL COMMENT "用户所在城市",
  `age` smallint(6) NULL COMMENT "用户年龄",
  `sex` tinyint(4) NULL COMMENT "用户性别",
  `last_visit_date` datetime REPLACE NULL DEFAULT "1970-01-01 00:00:00" COMMENT "用户最后一次访问时间",
  `cost` bigint(20) SUM NULL DEFAULT "0" COMMENT "用户总消费",
  `max_dwell_time` int(11) MAX NULL DEFAULT "0" COMMENT "用户最大停留时间",
  `min_dwell_time` int(11) MIN NULL DEFAULT "99999" COMMENT "用户最小停留时间"
) ENGINE=OLAP
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
COMMENT "OLAP"
PARTITION BY RANGE(`date`)
(PARTITION p201701 VALUES [('0000-01-01'), ('2017-02-01')),
PARTITION p201702 VALUES [('2017-02-01'), ('2017-03-01')),
PARTITION p201703 VALUES [('2017-03-01'), ('2017-04-01')))
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES (
"replication_num" = "1",
"in_memory" = "false",
"storage_format" = "V2"
);
-- 插入测试数据
insert into expamle_range_tbl  values(11111,'2017-01-01','2000-11-11 11:11:11','bj',111,1,'2022-01-01 00:00:00',1000,11,22);
insert into expamle_range_tbl  values(11112,'2017-02-22','2000-11-11 11:11:11','bj',111,1,'2022-01-01 00:00:00',1000,11,22);
insert into expamle_range_tbl  values(11113,'2017-03-22','2000-11-11 11:11:11','bj',111,1,'2022-01-01 00:00:00',1000,11,22);
-- 查询正式分区验证 
select * from expamle_range_tbl PARTITION(p201701,p201702,p201703);

验证分区插入结果

-- 创建临时分区
ALTER TABLE expamle_range_tbl ADD TEMPORARY PARTITION tp1 VALUES LESS THAN("2017-02-01");
-- 插入数据到临时分区
INSERT INTO expamle_range_tbl TEMPORARY PARTITION(tp1) values(11115,'2017-01-01','2017-01-01 11:11:11','sh',111,1,'2022-11-11 00:00:00',100,11,22);
-- 从临时分区查询数据验证
select * from expamle_range_tbl TEMPORARY PARTITION(tp1);
select * from expamle_range_tbl  PARTITION(tp1);

-- replace分区  use_temp_partition_name  的作用就是 若为 true  则分区 p201701 会删除掉,只能使用 修正过的正式分区   tp1 查询
-- 若为false  则原正式分区 p201701  还会保留只是下面的数据替换为 临时分区  tp1 下面的了,可以继续使用 正式分区查询
ALTER TABLE expamle_range_tbl REPLACE PARTITION (p201701) WITH TEMPORARY PARTITION (tp1)
PROPERTIES (
    "strict_range" = "true",
    "use_temp_partition_name" = "true"
);
-- 最终效果就是  p201701 分区将被删除掉,包括分区信息和分区下面的数据; 临时分区也将不存在,使用 tp1 名称 作为正式分区

select * from expamle_range_tbl PARTITION(p201701);

select * from expamle_range_tbl PARTITION(p201702,p201703);

select * from expamle_range_tbl PARTITION(tp1); 如下结果可以发现 就是之前的临时分区 tp1 的数据

select * from expamle_range_tbl; 以下可以发现临时分区的数据对于正式分区不可见。

ALTER TABLE expamle_range_tbl DROP TEMPORARY PARTITION tp1;
ALTER TABLE expamle_range_tbl DROP PARTITION tp1;
坑洼区:
若 strict_range 为true模式,并且他们分区范围并集不一样则会出现下述错误:

strict_range 为 false了, 但是需要保证分区范围不重叠,则会报下述错误。 意思是最左边界 和 最右边界 必须一样,否则也不行

临时分区的导入和查询

导入临时分区

INSERT INTO tbl TEMPORARY PARTITION(tp1, tp2, ...) SELECT ....
curl --location-trusted -u root: -H "label:123" -H "temporary_partitions: tp1, tp2, ..." -T testData http://host:port/api/testDb/testTbl/_stream_load

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

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
(...)
FROM KAFKA
(...);

和其他操作的关系

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

TRUNCATE
使用 Truncate 命令清空表,表的临时分区会被删除,且不可恢复。
使用 Truncate 命令清空正式分区时,不影响临时分区。
不可使用 Truncate 命令清空临时分区。

ALTER
当表存在临时分区时,无法使用 Alter 命令对表进行 Schema Change、Rollup 等变更操作。
当表在进行变更操作时,无法对表添加临时分区。

最佳实践

  1. 原子的覆盖写操作
    Doris不支持覆盖写,只能先删除后插入,但是这样会导致一段时间的不可读,因此可以先写入临时分区,然后搞一个分区替换就行了
  2. 修改分桶数
    原始表分桶数设置不合理, 可以设置一个和原分区分区范围一致的虚拟分区,然后使用 insert into select 把原始分区的数据写入虚拟分区,再来个分区替换就达到修改分区的效果
  3. 合并或分割分区
    分区range 设置的不合理,用户想缩小或者扩大分区,那么就可以设置对应的虚拟分区,然后使用 insert into select 把原始分区的数据写入虚拟分区,再来个分区替换就达到分区扩缩容的效果。

posted on 2021-11-24 16:03  踏雪扬尘-wx  阅读(1972)  评论(0编辑  收藏  举报