В этом документе описывается политика автоматического управления секциями и её использование в YMatrix.
В производственных средах данные часто секционируются по времени. YMatrix предоставляет несколько пользовательских функций (UDF) для управления секциями, позволяя администраторам вручную поддерживать секции в соответствии с требованиями — например, создавать одну секцию в день или каждые 8 часов.
Однако время является бесконечной размерностью. При создании секционированных таблиц администраторы обычно заранее создают секции только на ограниченный период в будущем, а затем периодически добавляют новые. Это увеличивает эксплуатационные издержки.
Автоматическое управление секциями устраняет необходимость ручного обслуживания за счёт автоматизации операций жизненного цикла секций, тем самым снижая административную нагрузку. Поддерживаются следующие функции:
Функциональность автоматического управления секциями включена в расширение matrixts. Следовательно, сначала необходимо создать расширение matrixts:
=# CREATE EXTENSION matrixts;
Используйте функцию set_policy(), чтобы назначить политику целевой таблице и включить автоматическое обслуживание секций.
В настоящее время поддерживаются три политики:
auto_partitioningauto_splittingauto_partitioning_exПримечание!
Начиная с версии 5.0, YMatrix представляет политикуauto_partitioning_ex. Используйте эту политику вместоauto_partitioning, чтобы воспользоваться расширенными возможностями, такими как пакетное создание секций, принудительное сохранение определённых исторических секций и настраиваемые временные окна операций.
Политика auto_partitioning включает автоматическое управление обычными секционированными таблицами и предоставляет две возможности автоматизации:
Пример: создайте тестовую секционированную таблицу с именем metrics:
=# CREATE TABLE metrics(
time timestamp with time zone,
tag_id int,
read float,
write float
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,tag_id)
PARTITION BY RANGE (time);
Назначьте таблице metrics политику автоматического секционирования auto_partitioning:
=# SELECT set_policy(
'metrics'::regclass,
'auto_partitioning'
);
Если требуется указание схемы, передайте параметр как
'schema_name.metrics'.
После установки политики используйте list_policy(), чтобы просмотреть её:
=# SELECT * FROM list_policy('metrics'::regclass);
reloid | relname | class_id | class_name | action | seq | disabled | check_func | check_args | act_func | act_args | versi
on
--------+---------+----------+-------------------+-------------+-----+----------+----------------------------------------+----------------------+------------------------------------------------+-----------------------+------
---
23361 | metrics | 2 | auto_partitioning | retention | 1 | t | matrixts_internal.apm_generic_expired | {"after": "1 year"} | matrixts_internal.apm_generic_drop_partition | {} | 1.0
23361 | 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 включает два действия:
retention: удаление устаревших секцийauto_create: создание новых секцийДействие retention использует проверочный аргумент {"after": "1 year"}, что означает, что любая секция старше одного года будет удалена.
Действие auto_create проверяет, должна ли быть создана новая секция, используя значение {"before": "3 days"} — то есть за три дня до наступления — и создаёт секции с временным интервалом {"period": "8 hours"}. Это значения по умолчанию для политики auto_partitioning.
Чтобы изменить эти параметры, вызовите set_policy_action().
Пример: измените retention, чтобы удалять секции после трёх месяцев; измените auto_create, чтобы просматривать вперёд на 2 дня и создавать суточные секции:
=# SELECT set_policy_action(
'metrics'::regclass,
'retention',
'3 months'
);
=# SELECT set_policy_action(
'metrics'::regclass,
'auto_create',
'{
"before": "2 days",
"period": "1 day"
}'
);
Примечание!
Для действий с одним параметром укажите целевое значение непосредственно в виде строки (например,'3 months'). Для действий с несколькими параметрами используйте JSON-объект для указания всех аргументов (например,'{"before": "2 days", "period": "1 day"}').
Политика auto_splitting применяется к секционированным таблицам, содержащим секцию по умолчанию. Она автоматически разделяет секцию по умолчанию на основе времени.
Пример: создайте секционированную таблицу и определите секцию по умолчанию:
=# CREATE TABLE metrics(
time timestamp with time zone,
tag_id int,
read float,
write float
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,tag_id)
PARTITION BY RANGE (time);
=# CREATE TABLE metrics_others PARTITION OF metrics DEFAULT;
Примените политику auto_splitting:
=# SELECT set_policy(
'metrics'::regclass,
'auto_splitting'
);
Просмотрите политику:
=# SELECT * FROM list_policy('metrics'::regclass);
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 включает два действия: retention (удаление устаревших секций) и auto_split (автоматическое разделение секции по умолчанию).
Здесь {"age": "1 month 2days"} означает, что разделение запускается, когда самые старые данные в секции по умолчанию старше 1 месяца и 2 дней.
{"period": "1 month"} указывает, что каждая полученная секция покрывает интервал в 1 месяц.
Политика auto_partitioning_ex расширяет функциональность auto_partitioning, предлагая расширенные возможности управления секциями:
Эти функции подробно описаны в приведённых ниже примерах.
Создайте секционированную таблицу и определите специальную секцию:
=# CREATE TABLE metrics(
time timestamp with time zone,
tag_id int,
read float,
write float
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,tag_id)
PARTITION BY RANGE (time);
=# CREATE TABLE metrics_invalid_apmtrap PARTITION OF metrics FOR VALUES FROM ('-infinity') TO ('2023-01-01');
Установите политику auto_partitioning_ex:
=# SELECT set_policy(
'metrics'::regclass,
'auto_partitioning_ex'
);
Просмотрите политику:
=# SELECT * FROM list_policy('metrics'::regclass);
reloid | relname | class_id | class_name | action | seq | disabled | check_func | check_args
| act_func | act_args | version
--------+---------+----------+----------------------+-------------+-----+----------+-------------------------------------------+---------------------------------------------------------------------------------------------------------------------
-------------------+------------------------------------------------+-----------------------+---------
34917 | metrics | 4 | auto_partitioning_ex | retention | 1 | t | matrixts_internal.apm_generic_expired | {"after": "1 year"}
| matrixts_internal.apm_generic_drop_partition | {} | 1.0
34917 | metrics | 4 | auto_partitioning_ex | auto_create | 2 | f | matrixts_internal.apm_generic_incoming_ex | {"before": "3 days", "period": "8 hours", "end_time": "00:00:00", "batch_size": "0", "start_time": "00:00:00", "stor
age_type": "heap"} | matrixts_internal.apm_generic_append_partition | {"period": "8 hours"} | 1.0
(2 rows)
Из вывода видно, что действие auto_create в рамках auto_partitioning_ex имеет параметры "before": "3 days" и "period": "8 hours". Это означает, что автоматизированная система обеспечит предварительное создание всех секций на следующие 3 дня, при этом каждая из них будет покрывать интервал в 8 часов. Например, если текущее время — 1 марта, 00:01, система запустит создание секций и обеспечит готовность всех секций до 4 марта, 00:00. В момент 4 марта, 00:00 система начнёт создавать следующую 8-часовую секцию (4 марта, 00:00–08:00). Такой подход гарантирует, что политика auto_partitioning_ex всегда заранее подготовит секции на ближайшие 3 дня.
Однако другие параллельные задачи могут удерживать блокировки таблицы, что вызывает конфликты блокировок при попытке автоматической системы создать секции. Чтобы уменьшить частоту таких конфликтов, политика auto_partitioning_ex вводит опцию batch_size.
Установите её с помощью следующей команды:
=# SELECT public.set_policy_action('metrics'::regclass, 'auto_create', '{ "batch_size": "4" }');
Это означает, что всякий раз, когда нужно создать новую секцию, система одновременно создаст ещё 4 будущие секции. Таким образом, при создании секции 4 марта, 00:00–08:00 в 1 марта, 00:01, будут также созданы следующие четыре 8-часовые секции: 4 марта, 08:00–16:00; 4 марта, 16:00–24:00; 5 марта, 00:00–08:00; и 5 марта, 08:00–16:00.
Это позволяет избежать повторного запуска создания секций между 1 и 4 марта, тем самым снижая конкуренцию за блокировки.
batch_size — 0, что означает отсутствие пакетного режима — поведение идентично auto_partitioning.batch_size — 7.Примечание!
Хотя пакетное создание уменьшает частоту конфликтов блокировок (например, с ежедневного до раз в несколько дней), оно не может полностью устранить конфликты блокировок при выполнении автоматической задачей DDL-операций. Это ограничение обусловлено базовыми механизмами параллелизма в базах данных.
Поэтому необходимо обеспечить надлежащий мониторинг запросов, блокировок и выполнения автоматического управления секциями.
Как показано выше, мы создали секцию с именем metrics_invalid_apmtrap. Когда включена функция retention (автоматическое удаление секций) в рамках auto_partitioning_ex, любая секция, имя которой содержит строку apmtrap (например, metrics_invalid_apmtrap), не будет удалена, даже если она соответствует условию истечения срока. Это обеспечивает постоянное хранение назначенных исторических секций.
Эта функция предназначена для реализации «ловушки» — секции, которая собирает данные вне диапазона (например, метки времени вроде 1970-01-01). Такая ловушка поглощает недопустимые данные, которые в противном случае попали бы в секцию по умолчанию, предотвращая её быстрый рост. Кроме того, поскольку эта секция не участвует в запросах или DDL-операциях, это помогает сохранить производительность запросов.
Из предыдущего результата list_policy() обратите внимание на параметры start_time и end_time в поле check_args. Эти параметры контролируют временное окно, в течение которого могут выполняться задачи автоматического управления секциями, помогая избежать создания секций в часы пиковой нагрузки.
Например:
"start_time": "01:00:00", "end_time": "04:00:00" разрешает операции ежедневно с 1:00 до 4:00.
"start_time": "22:00:00", "end_time": "03:00:00" разрешает операции с 22:00 до 3:00 следующего дня.
Значение по умолчанию для обоих полей — "00:00:00", что означает отсутствие временных ограничений — операции разрешены в любое время.
Пример:
SELECT public.set_policy_action('table_name'::regclass, 'auto_create', '{ "start_time": "00:00:00", "end_time": "04:00:00" }');
Примечание!
Временное окно должно быть не менее 1 часа. Интервал проверки по умолчанию для автоматического управления секциями составляет 1 час. Окно короче 1 часа может пропустить момент запуска.
Достижениеend_timeне приводит к немедленному завершению выполняющихся операций. Любая запущенная задача продолжается до завершения.end_timeлишь предотвращает начало новых проверок после этого момента — он не принудительно останавливает выполняющиеся задачи. Поэтому при установкеend_timeследует предусмотреть достаточное резервное время до следующего периода пиковой нагрузки.
Из вывода list_policy() обратите внимание на столбец disabled. Этот столбец управляет активностью действия политики. По умолчанию, независимо от типа политики, действие retention отключено.
Чтобы включить действие, используйте enable_policy_action():
=# SELECT enable_policy_action('metrics'::regclass, 'retention');
Чтобы отключить действие, используйте disable_policy_action():
=# SELECT disable_policy_action('metrics', 'auto_split');
Используйте drop_policy(), чтобы удалить политику из секционированной таблицы:
=# SELECT drop_policy('metrics'::regclass);
Примечание!
Каждая секционированная таблица может иметь только одну политику секционирования. Поэтому для удаления политики достаточно указать только имя таблицы.
Таблица apm_operation_log регистрирует каждую операцию пользователя, выполненную при настройке APM. Пример:
=# 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)
Таблица apm_action_log регистрирует каждую операцию автоматического секционирования, выполняемую фоновым процессом APM. Пример:
=# (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)