自动化分区管理

本文档介绍了 YMatrix 中的自动化分区管理策略及使用。

在生产环境中,常按时间做数据分区。YMatrix 提供了一些用来管理分区的 UDF(User Defined Functions),你可以根据自己的需求手动做分区维护。如:每天一个分区,每 8 个小时一个分区等。但时间是一个无限延伸的维度,在创建分区表的时候管理员通常只是提前将未来一段时间内的分区创建好,然后定期增加新的时间段分区。这无疑增加了运维成本。

自动化分区管理就是将手动维护分区的工作自动化,从而降低管理员维护数据库的成本。包括:

  1. 分区自动创建与删除
  2. 默认分区自动切分

自动化分区管理功能包含在 matrixts 扩展中,所以首先要创建 matrixts 扩展:

CREATE EXTENSION matrixts;

通过调用 set_policy,为目标表设置策略,来实现分区维护自动化:

目前包含如下2种策略:

  1. auto_partitioning
  2. auto_splitting

1 auto_partitioning

auto_partitioning 策略应用于普通分区表的自动化管理,实现了如下 2 种自动化功能:

  1. 新分区创建
  2. 过期分区清理

示例,创建测试分区表 metrics,如下:

CREATE TABLE metrics(
    time timestamp with time zone,
    tag_id int,
    read float,
    write float
)
DISTRIBUTED BY (tag_id)
PARTITION BY RANGE (time);

为 metrics 表创建 auto_partitioning 自动分区策略:

SELECT set_policy(
    'metrics',
    'auto_partitioning'
);

如果需要携带模式信息的话,传递参数 schema_name.table_name 即可。

设置好策略后,调用 list_policy 查看策略:

SELECT * FROM list_policy('metrics');

 reloid | relname | class_id |    class_name     |   action    | seq | disabled |               check_func               |      check_args      |                    act_func                    |       act_args        | version
--------+---------+----------+-------------------+-------------+-----+----------+----------------------------------------+----------------------+------------------------------------------------+-----------------------+---------
  17798 | metrics |        2 | auto_partitioning | retention   |   1 | t        | matrixts_internal.apm_generic_expired  | {"after": "1 year"}  | matrixts_internal.apm_generic_drop_partition   | {}                    | 1.0
  17798 | metrics |        2 | auto_partitioning | auto_create |   2 | f        | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_partition | {"period": "8 hours"} | 1.0
(2 rows)

可以看到,auto_partitioning 总共包含两种操作:

  1. retention:过期分区删除
  2. auto_create:新分区创建

其中 retention 的检测参数是 {"after": "1 year"} ,即检测分区是否超过一年,然后删除。 auto_create 的检测参数是 {"before": "3 days"},即提前 3 天检测是否需要创建新分区;执行参数为 {"period": "8 hours"},即创建新分区的时间跨度为 8 小时。这是 auto_partitioning 策略的默认设置。

如果要调整这些参数,需要调用 set_policy_action

示例,将 retention 调整为 3 个月后自动删除;auto_create 调整为提前 2 天,时间跨度为 1 天:

postgres=# SELECT set_policy_action(
    'metrics',
    'retention',
    '3 months'
);

postgres=# SELECT set_policy_action(
    'metrics',
    'auto_create',
    '{
        "before": "2 days",
        "period": "1 day"
    }'
);

注意!
对于只有一个参数的 action 来说,直接写目标值字符串即可,如 retention。对于包含多个参数的 action,目标值需要通过 JSON 拼接完成。

2 auto_splitting

auto_splitting 策略对包含默认分区的分区表,实现默认分区按时间切割操作。

示例,创建分区表,并为之创建默认分区:

postgres=# CREATE TABLE metrics(
    time timestamp with time zone,
    tag_id int,
    read float,
    write float
)
DISTRIBUTED BY (tag_id)
PARTITION BY RANGE (time);

postgres=# CREATE TABLE metrics_others PARTITION OF metrics DEFAULT;

设置 auto_splitting 策略:

postgres=# SELECT set_policy(
    'metrics',
    'auto_splitting'
);

查看策略:

postgres=# SELECT * FROM list_policy('metrics');
 reloid | relname | class_id |   class_name   |   action   | seq | disabled |                check_func                |        check_args        |                       act_func                        |       act_args        | version
--------+---------+----------+----------------+------------+-----+----------+------------------------------------------+--------------------------+-------------------------------------------------------+-----------------------+---------
  17798 | metrics |        1 | auto_splitting | retention  |   1 | t        | matrixts_internal.apm_generic_expired    | {"after": "1 year"}      | matrixts_internal.apm_generic_drop_partition          | {}                    | 1.0
  17798 | metrics |        1 | auto_splitting | auto_split |   2 | f        | matrixts_internal.apm_generic_older_than | {"age": "1 month 2days"} | matrixts_internal.apm_generic_split_default_partition | {"period": "1 month"} | 1.0
(2 rows)

可以看到,auto_splitting 策略包含2种操作,过期分区删除 retention 和默认分区自动切割 auto_split

其中,{"age": "1 month 2days"} 表示当默认分区中最老的数据早于当前时间1月零2天前的时候,进行切割。{"period": "1 month"} 表示切割后分区粒度为1个月。

3 操作状态设置

从上面 list_policy 结果会注意到,包含一个叫做 disabled 的列。该列用来设置操作生效状态。目前无论哪种策略,retention 操作的状态都是disabled。

如要开启该操作,请调用 enable_policy_action

postgres=# SELECT enable_policy_action('metrics', 'retention');

如要禁用一种操作,请调用 disable_policy_action

postgres=# SELECT disable_policy_action('metrics', 'auto_split');

4 删除策略

drop_policy 为分区表删除策略:

postgres=# SELECT drop_policy('metrics');

注意!
每个分区表只能设置一种分区策略,所以删除策略只提供分区表名即可。

5 日志监控

5.1 apm_operation_log

apm_operation_log 记录了用户配置APM的每个操作履历。示例如下:

matrixmgr=# SELECT username = CURRENT_USER, relname, class_id, class_name, action, operation, mod_field, old_val, new_val
FROM matrixts_internal.apm_operation_log ORDER BY ts;
 ?column? |      relname       | class_id | class_name |   action   | operation | mod_field  |        old_val         |        new_val         
----------+--------------------+----------+------------+------------+-----------+------------+------------------------+------------------------
 t        | apm_test.split_set |          |            | test_split | add       | check_args |                        | {"age": "1 month"}
 t        | apm_test.split_set |          |            | test_split | add       | act_args   |                        | {"period": "2 weeks"}
 t        | apm_test.split_set |          |            | test_split | mod       | act_args   | {"period": "2 weeks"}  | {"period": "12 hours"}
 t        | apm_test.split_set |          |            | test_split | mod       | check_args | {"age": "1 month"}     | {"age": "15 days"}
 t        | apm_test.split_set |          |            | test_split | mod       | check_args | {"age": "15 days"}     | {"age": "5 days"}
 t        | apm_test.split_set |          |            | test_split | mod       | act_args   | {"period": "12 hours"} | {"period": "2 days"}
 t        | apm_test.split_set |          |            | test_split | drop      |            |                        | 
 t        | apm_test.split_set |          |            | test_split | add       | check_args |                        | {"age": "10 days"}
 t        | apm_test.split_set |          |            | test_split | add       | act_args   |                        | {"period": "1 hour"}
(9 rows)

5.2 apm_action_log

apm_action_log 记录APM后台每次自动发生分区操作的履历。示例如下:

matrixmgr=# (select * from matrixts_internal.apm_action_log order by ts limit 6) union all (select * from matrixts_internal.apm_action_log order by ts desc limit 6) order by 1;
             ts             |  pid  | reloid |         relname          |      nspname       | class_id |    class_name     |   action    |               check_func               |      check_args      |                    act_func
      |      act_args       |  state  |      message      | details | addopt |  client
----------------------------+-------+--------+--------------------------+--------------------+----------+-------------------+-------------+----------------------------------------+----------------------+------------------------------------------
------+---------------------+---------+-------------------+---------+--------+----------
 2022-11-18 15:48:45.963264 | 15776 |  18360 | mx_query_execute_history | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | START   | action start      |         |        | schedule
 2022-11-18 15:48:46.165418 | 15776 |  18360 | mx_query_execute_history | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | SUCCESS | do action success |         |        | schedule
 2022-11-18 15:48:46.172096 | 15776 |  18373 | mx_query_usage_history   | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | START   | action start      |         |        | schedule
 2022-11-18 15:48:46.332781 | 15776 |  18373 | mx_query_usage_history   | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | SUCCESS | do action success |         |        | schedule
 2022-11-19 00:48:45.992494 | 24930 |  18360 | mx_query_execute_history | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | START   | action start      |         |        | schedule
 2022-11-19 00:48:46.064604 | 24930 |  18360 | mx_query_execute_history | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | SUCCESS | do action success |         |        | schedule
 2022-11-21 00:48:47.708846 | 14091 |  18373 | mx_query_usage_history   | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | START   | action start      |         |        | schedule
 2022-11-21 00:48:47.812423 | 14091 |  18373 | mx_query_usage_history   | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | SUCCESS | do action success |         |        | schedule
 2022-11-22 00:48:46.552925 |  8539 |  18360 | mx_query_execute_history | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | START   | action start      |         |        | schedule
 2022-11-22 00:48:53.25854  |  8539 |  18360 | mx_query_execute_history | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | SUCCESS | do action success |         |        | schedule
 2022-11-22 00:48:53.261857 |  8539 |  18373 | mx_query_usage_history   | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | START   | action start      |         |        | schedule
 2022-11-22 00:48:55.625125 |  8539 |  18373 | mx_query_usage_history   | matrixmgr_internal |        2 | auto_partitioning | auto_create | matrixts_internal.apm_generic_incoming | {"before": "3 days"} | matrixts_internal.apm_generic_append_part
ition | {"period": "1 day"} | SUCCESS | do action success |         |        | schedule
(12 rows)