F.39. pgpro_autopart — динамическое создание секций #
Расширение pgpro_autopart позволяет создавать секции динамически, то есть производит автоматическое секционирование при добавлении или изменении данных в таблице. Самый быстрый способ создания секций — вручную или по расписанию с помощью планировщика. Однако для некоторых задач скорость добавления данных не имеет большого значения. Для таких задач pgpro_autopart реализует автоматическое секционирование с помощью триггеров для представления секционированной таблицы.
F.39.1. Установка #
Расширение pgpro_autopart входит в состав Postgres Pro. Чтобы его задействовать, создайте расширение следующим запросом:
CREATE EXTENSION pgpro_autopart;
F.39.2. Использование #
Расширение pgpro_autopart использует для автоматического секционирования функцию ap_enable_automatic_partition_creation
.
Примечание
Обратите внимание, что расширение работает только с новыми таблицами. Его нельзя использовать для существующих секционированных таблиц, поскольку оно не может отслеживать секции, которые были созданы пользователями ранее.
Сначала функция добавляет к имени указанной таблицы префикс real_
, а затем создаёт представление с первоначальным именем таблицы и триггеры INSTEAD OF INSERT/UPDATE
для этого представления.
Примечание
Обратите внимание, что администратор баз данных должен вручную предоставлять права на представление, созданное функцией ap_enable_automatic_partition_creation
. Ожидается, что это будут те же права, что и для родительской таблицы.
Эти триггеры работают следующим образом:
INSTEAD OF INSERT
: при попытке добавить запись в представление pgpro_autopart ищет секцию для этой записи. Если секция не найдена, она создаётся, после чего запись добавляется в секционированную таблицу.INSTEAD OF UPDATE
: при попытке изменить запись в представлении pgpro_autopart ищет секцию для этой записи. Если секция не найдена, она создаётся, после чего запись изменяется в секционированной таблице.
В настоящее время поддерживаются только таблицы с секционированием по диапазону значения ключа (BY RANGE
), которым должен быть один столбец типа date
, timestamp
, timestamptz
, smallint
, int
или bigint
.
При создании секций для ключа секционирования типа date
/timestamp
допустимыми значениями интервала являются year
, quarter
, month
и day
. То есть новая секция создаётся для каждого нового года, квартала, месяца или дня.
Имена новых секций следуют строго определённому формату: к имени секционированной таблицы добавляется суффикс, указывающий интервал, для которого создаётся секция. Например:
day
real_t_day_2024_05_13
для таблицыreal_t_day
month
real_t_month_2024_05
для таблицыreal_t_month
quarter
real_t_quarter_2024_2
для таблицыreal_t_quarter
year
real_t_year_2025
для таблицыreal_t_year
int
real_t_int_120_130
для таблицыreal_t_int
bigint
"real_t_bigint_-60_-50"
для таблицыreal_t_bigint
Триггеры INSTEAD OF INSERT/UPDATE
проверяют наличие секции для каждой вставляемой или изменяемой записи, что может несколько замедлить работу.
Поскольку исходная секционированная таблица переименовывается, для продолжения работы непосредственно с этой таблицей следует добавлять префикс real_
.
Важно
Помните, что максимальная длина имени таблицы в Postgres Pro — 63 байта. Когда расширение pgpro_autopart создаёт секцию, оно автоматически добавляет до 29 байт (префикс real_
, два подчёркивания, символы границ) к имени таблицы для типа int
и до 51 байта для ключа секционирования типа bigint
. Ответственность за выбор соответствующих имён таблиц, чтобы избежать ошибок, лежит на пользователе.
F.39.3. Представление ap_tables_view #
Таблицы с включённым автоматическим секционированием показаны в представлении ap_tables_view
. Ниже приведён пример данных в этом представлении.
SELECT * FROM ap_tables_view; apt_relname | apt_relschema | apt_mode -------------+---------------+----------------------------------------------------------------------------- t_month1 | user_schema | automatic partition creation with using triggers on VIEW (C-implementation) t_bigint1 | user_schema | automatic partition creation with using triggers on VIEW (C-implementation) (2 rows)
F.39.4. Функции #
-
ap_enable_automatic_partition_creation(a_relname text[, a_relschema text], a_interval text) returns void
# Эта функция предназначена для таблиц с ключом секционирования типа
date
,timestamp
илиtimestampz
. Она переименовывает секционированную таблицуa_relname
(схемыa_relschema
), добавляя префиксreal_
, а затем создаёт представление с тем же именем, что и у исходной таблицы, и добавляет для него триггерыINSTEAD OF INSERT/UPDATE
. Эти триггеры при необходимости создают новую секцию, границы которой определяются интервалом, заданным в параметреa_interval
(год, квартал, месяц, день).-
ap_enable_automatic_partition_creation(a_relname text[, a_relschema text], a_interval smallint, a_firstval smallint) returns void
ap_enable_automatic_partition_creation(a_relname text[, a_relschema text], a_interval int, a_firstval int) returns void
ap_enable_automatic_partition_creation(a_relname text[, a_relschema text], a_interval bigint, a_firstval bigint) returns void
# Эти функции используются для таблиц с ключом секционирования типа
smallint
,int
илиbigint
. Они переименовывают секционированную таблицуa_relname
(схемыa_relschema
), добавляя префиксreal_
. Затем вызванная функция создаёт представление с тем же именем, что и у исходной таблицы, и триггерыINSTEAD OF INSERT/UPDATE
для него. Эти триггеры при необходимости создают новую секцию, границы которой определяются исходным значениемa_firstval
, от которого отсчитываются интервалы, и значениемa_interval
, определяющим длину интервала.-
ap_disable_automatic_partition_creation(a_relname text[, a_relschema text]) returns void
# Функция удаляет триггеры, созданные функцией
ap_enable_automatic_partition_creation
для представления указанной секционированной таблицыa_relname
(схемыa_relschema
). Она также удаляет представление и переименовывает секционированную таблицу, убирая из её имени префиксreal_
.
F.39.5. Пример #
В следующем примере показано использование расширения pgpro_autopart с ключом секционирования типа bigint
.
Создайте расширение.
CREATE EXTENSION pgpro_autopart;
Создайте таблицу, секционированную с указанием BY RANGE
с одностолбцовым ключом типа bigint
.
CREATE TABLE t_bigint (b bigint, i int) PARTITION BY RANGE (b);
Используйте расширение, чтобы переименовать таблицу t_bigint
в real_t_bigint
, создать представление t_bigint
для этой таблицы, а затем создать триггеры INSTEAD OF INSERT/UPDATE
. Обратите внимание, что начальное значение для создания секций — 100, а секции создаются с интервалом 10 в обоих направлениях.
SELECT ap_enable_automatic_partition_creation('t_bigint', 10, 100); ap_enable_automatic_partition_creation ---------------------------------------- (1 row)
Добавьте две записи в таблицу. При добавлении первой записи будет автоматически создана секция real_t_bigint_110_120
.
INSERT INTO t_bigint VALUES (111, 1); NOTICE: New partition "public"."real_t_bigint_110_120" created INSERT 0 1 INSERT INTO t_bigint VALUES (114, 2); INSERT 0 1
Измените у одной из записей поле ключа. При этом будет автоматически создана секция real_t_bigint_-60_-50
.
UPDATE t_bigint SET b = -55 WHERE b = 114 RETURNING *; NOTICE: New partition "public"."real_t_bigint_-60_-50" created b | i -----+--- -55 | 2 (1 row) UPDATE 1
Проверьте секции таблицы real_t_bigint
. Их должно быть две.
SELECT c.oid::pg_catalog.regclass AS "name", pg_catalog.pg_get_expr(c.relpartbound, c.oid) AS "condition" FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid = i.inhrelid AND i.inhparent = 'real_t_bigint'::regclass; name | condition -------------------------+------------------------------------ real_t_bigint_110_120 | FOR VALUES FROM ('110') TO ('120') "real_t_bigint_-60_-50" | FOR VALUES FROM ('-60') TO ('-50') (2 rows)
Проверьте данные в таблице real_t_bigint
и её секциях. В таблице должно быть две записи:
SELECT * FROM real_t_bigint; b | i -----+--- -55 | 2 111 | 1 (2 rows)
В секции real_t_bigint_110_120
должна быть одна запись:
SELECT * FROM real_t_bigint_110_120; b | i -----+--- 111 | 1 (1 row)
Также должна быть одна запись в секции real_t_bigint_-60_-50
.
SELECT * FROM "real_t_bigint_-60_-50"; b | i -----+--- -55 | 2 (1 row)
Отключите триггеры, удалите представление и переименуйте таблицу real_t_bigint
в t_bigint
.
SELECT ap_disable_automatic_partition_creation('t_bigint'); ap_disable_automatic_partition_creation ----------------------------------------- (1 row)
Удалите таблицу и расширение.
DROP TABLE t_bigint; DROP TABLE DROP EXTENSION pgpro_autopart; DROP EXTENSION