写点什么

带你认识一下数仓的分区自动管理

  • 2022 年 7 月 20 日
  • 本文字数:3272 字

    阅读完需:约 11 分钟

带你认识一下数仓的分区自动管理

本文分享自华为云社区《GaussDB(DWS) 分区自动管理介绍》,作者: Attila。


对于分区列为时间的分区表,分区自动管理功能可以自动创建新分区和删除过期分区,降低分区表的维护成本,改善查询性能。下面将从分区自动管理的作用、用法、原理等方面进行介绍。

1. 分区自动管理作用


为了便于查询和维护数据,客户通常使用分区列为时间的分区表来存储时间相关的数据,例如电商的订单信息、 物联网采集的实时数据。这些时间相关的数据导入分区表时,需要保证分区表要有对应时间的分区,由于普通的分区表不会自动创建新的分区和删除过期分区,所以维护人员需要定期创建新分区和删除过期分区,提高了运维成本。


为解决上述问题,GaussDB(DWS) 引入了分区自动管理特性。使用者可通过设置表级参数 period、ttl 开启分区自动管理功能,使分区表可以自动创建新分区和删除过期分区,降低分区表的维护成本,改善查询性能。其中,period 既表示新分区的时间范围,也表示自动创建新分区和自动删除过期分区的周期;ttl 表示分区过期时间。period 和 ttl 的值均为 Interval 类型,例如'1 hour'、'1 day'、'1 week'、'1 month'、'1 year'、 '1 month 2 days 3 hours'等。

1.1 自动创建新分区


分区自动管理每隔周期的时间就会自动创建分区,每次创建一个或多个时间范围为周期的新分区,以推进最大的分区边界时间,保证其大于 nowTime+30*period。由于每次创建分区时,都动态地为未来时间创建了预留分区,所以只要有一次自动创建新分区成功,就可以保证在未来 30 个 period 的时间之内,都不会出现实时数据因为没有对应分区而导入失败的情况。


1.2 自动删除过期分区


边界时间早于 nowTime-ttl 的分区被认为是过期分区。分区自动管理每隔 period 的时间就会遍历检测所有分区,并删除其中的过期分区,如果所有的分区都是过期分区,则保留一个分区,并 truncate 该表。

2. 分区自动管理用法

2.1 分区管理功能约束


在使用分区管理功能时,需要满足如下约束:


1)不支持在小型机、加速集群、单机集群上使用。

2)不支持在 8.1.3 版本以下的版本中使用。

3)仅支持行存范围分区表、列存范围分区表、时序表以及冷热表。

4)分区键唯一并且类型仅支持时间戳、timestamptz、date 类型。

5)不支持存在最大值分区。

6)(nowTime - boundaryTime) / period 需要小于分区个数上限,其中 nowTime 为当前时间,boundaryTime 为现有分区中最早的分区边界时间。

7)period、ttl 取值范围为 1 小时~100 年。另外,在兼容 Teradata 或 MySQL 的数据库中,分区键类型为 date 时,period 不能小于 1 天。

8)表级参数 ttl 不支持单独存在,必须要提前或同时设置 period,并且要大于或等于 period。

9)集群在线扩容期间,自动增加分区会失败,但是由于每次增分区时,都预留了足够的分区,所以不影响使用。

2.2 开启分区管理功能


分区管理功能是和表级参数 period、ttl 绑定的,只要成功设置了表级参数 period,即开启了自动创建新分区功能;成功设置了表级参数 ttl,即开启了自动删除过期分区功能。第一次自动创建分区或删除分区的时间为设置 period 或 ttl 后 30 秒。


有两种开启分区管理功能的方式,具体如下:


1)建表时指定 period、ttl


该方式适用于新建分区管理表时使用。新建分区管理表有两种语法,一种是建表时指定分区,另一种是建表时不指定分区。


建分区管理表时如果指定分区,则语法规则和建普通分区表相同,唯一的区别就是会指定表级参数 period、ttl,具体示例如下。在该示例中,分区过期时间为 7 days,新分区的时间范围以及自动分区任务周期为 1 day。


CREATE TABLE CPU1(	    id integer,		    IP text,	    time timestamp) with (TTL='7 days',PERIOD='1 day')partition by range(time)(	    PARTITION P1 VALUES LESS THAN('2022-01-05 16:32:45'),    PARTITION P2 VALUES LESS THAN('2022-01-06 16:56:12'));
复制代码

建分区管理表时可以只指定分区键不指定分区,此时将创建两个默认分区,这两个默认分区的分区时间范围均为 period。其中,第一个默认分区的边界时间是大于当前时间的第一个整时/整天/整周/整月/整年的时间,具体选择哪种整点时间取决于 period 的最大单位;第二个默认分区的边界时间是第一个分区边界时间加 period。假设当前时间是 2022-02-17 16:32:45,各种情况的第一个默认分区的分区边界选择如下表:



建表时不指定分区的具体示例如下:


CREATE TABLE CPU2(    id integer,	    IP text,	    time timestamp) with (TTL='7 days',PERIOD='1 day')partition by range(time);复制
复制代码


2)使用 alter table set 的方式设置 period、ttl


该方式适用于给一张满足分区管理约束的普通分区表增加分区管理功能。


假设 cpu3 表是一张满足分区管理约束的普通分区表,给该表增加分区管理功能的示例如下:


-- 同时开启自动创建和自动删除分区功能ALTER TABLE cpu3 SET (PERIOD='1 day',TTL='7 days');-- 只开启自动创建分区功能ALTER TABLE cpu3 SET (PERIOD='1 day');-- 只开启自动删除分区功能,如果没有提前开启自动创建分区功能,则开启失败ALTER TABLE cpu3 SET (TTL='7 days');
复制代码

2.3 修改分区管理功能


修改分区管理功能主要是修改 period 和 ttl,可以通过 alter table set 的方式修改。


假设 cpu4 表是一张分区管理表,修改其 period 和 ttl 示例如下:


-- 同时修改periodALTER TABLE cpu4 SET (TTL='10 days',PERIOD='2 days');
复制代码

2.4 关闭分区管理功能


使用 alter table reset 的方式可以删除表级参数 period、ttl,进而关闭相应的分区管理功能。需要注意的是,不能在存在 ttl 的情况下,单独删除周期。另外,时序表不支持 alter table reset。


假设 cpu5 表是一张具有 period 和 ttl 的分区管理表,关闭其分区管理功能示例如下:


-- 同时关闭自动创建和自动删除分区功能ALTER TABLE cpu5 RESET (PERIOD,TTL);-- 只关闭自动删除分区功能ALTER TABLE cpu5 RESET (TTL);-- 只关闭自动创建分区功能,如果该表有ttl参数,则关闭失败ALTER TABLE cpu5 RESET (PERIOD);
复制代码

3.分区自动管理原理

3.1 基本原理


分区管理的实现依托了 pg_task 自动调度任务,即设置 period/ttl 时,向 scheduler.pg_task 表中插入了自增/自减分区管理任务,其中自增分区任务的任务内容为 proc_add_partition(relname, period)函数,自减分区任务为 proc_drop_partition(relname, ttl)函数,两种任务的调用周期均为 period,第一次执行时间为任务插入时间后 30 秒。


使用管理员权限,可以查看 scheduler.pg_task 表中任务具体的信息,例如任务内容(what 字段)、任务执行周期(interval 字段)、任务上一次成功执行的时间(actual_end_time 字段)、任务状态(task_status 字段)。当自动调度任务执行失败时,用户可以复制 scheduler.pg_task 表中分区管理任务的 what 字段,然后手动执行该任务。查看 scheduler.pg_task 表以及手动执行自增分区任务示例如下:


my_database=# SELECT what,interval FROM scheduler.pg_task;                             what                             | interval--------------------------------------------------------------+---------- call proc_add_partition('public.cpu1', interval '1 day');    | 1 day call proc_drop_partition('public.cpu1', interval '7 days');  | 1 day(2 rows)
my_database=# call proc_add_partition('public.cpu1', interval '1 day'); proc_add_partition--------------------
(1 row)
复制代码

3.2 proc_add_partition(relname regclass, boundaries_interval interval)


该函数用于自动添加分区,具体实现流程如下图。函数运行时,会在分区表现有分区边界的基础上,创建多个时间范围为 boundaries_interval 的新分区,直到新的 boundary 距离当前时间大于 29 个 boundaries_interval,之后再额外多创建一个分区,保证该函数运行时,一定会创建一个新分区 。


3.3 proc_drop_partition(relname regclass,older_than 间隔)


该函数用于自动删除过期分区。函数运行时,会遍历分区表所有分区,并删除其中 boundary 早于(now_time - older_than)的分区;如果所有分区都满足删除条件,则保留一个分区,并 truncate 该表。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 5
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
带你认识一下数仓的分区自动管理_数据库_华为云开发者联盟_InfoQ写作社区