Миграция с триггерного разделения на декларативное разделение в PostgreSQL
В этом документе описывается, как перенести набор разделов, используя старый метод триггеров/наследования/ограничений, на набор разделов с использованием собственных функций PostgreSQL. Предполагается, что вы работаете с версией PostgreSQL 14 или выше. Этот документ не полностью переносит набор разделов для использования pg_partman, а только предоставляет общее руководство по процессу перехода от триггерной схемы к собственной схеме. Для миграции набора разделов на pg_partman обратитесь к отдельному документу migrate_to_partman.md.
Для субразбиения вы можете следовать тем же процессам, но вам придётся работать от самого нижнего уровня вверх и выполнять миграцию на каждом родительском уровне до верхнего родительского уровня.
Как всегда, рекомендуется сначала протестировать эту миграцию в системе разработки. Не требуется полный набор данных, достаточно схемы с небольшим набором данных в каждой дочерней таблице, чтобы убедиться, что она работает правильно.
Вот как выглядит наш набор разделов перед миграцией:
\d+ partman_test.time_taptest_table
Table "partman_test.time_taptest_table"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+--------------------------+-----------+----------+---------+----------+-------------+--------------+-------------
col1 | integer | | not null | | plain | | |
col2 | text | | | | extended | | |
col3 | timestamp with time zone | | not null | now() | plain | | |
Indexes:
"time_taptest_table_pkey" PRIMARY KEY, btree (col1)
Triggers:
time_taptest_table_part_trig BEFORE INSERT ON partman_test.time_taptest_table FOR EACH ROW EXECUTE FUNCTION partman_test.time_taptest_table_part_trig_func()
Child tables: partman_test.time_taptest_table_p2023_03_26,
partman_test.time_taptest_table_p2023_03_27,
partman_test.time_taptest_table_p2023_03_28,
partman_test.time_taptest_table_p2023_03_29,
partman_test.time_taptest_table_p2023_03_30,
partman_test.time_taptest_table_p2023_03_31,
partman_test.time_taptest_table_p2023_04_01,
partman_test.time_taptest_table_p2023_04_02,
partman_test.time_taptest_table_p2023_04_03,
partman_test.time_taptest_table_p2023_04_04,
partman_test.time_taptest_table_p2023_04_05,
partman_test.time_taptest_table_p2023_04_06,
partman_test.time_taptest_table_p2023_04_07,
partman_test.time_taptest_table_p2023_04_08,
partman_test.time_taptest_table_p2023_04_09
Access method: heap
Если ваш набор разделов на основе триггеров управляется версией pg_partman до 5.0.0, лучше всего удалить его из управления partman. Это можно сделать, удалив его из таблиц part_config
и part_config_sub
(если есть субразделение, убедитесь, что все дочерние таблицы также удалены). После переноса на собственное разделение см. упомянутый выше документ «Миграция на pg_partman», чтобы вернуть управление partman.
DELETE FROM partman.part_config WHERE parent_table = 'partman_test.time_taptest_table';
Если он не управляется pg_partman и у вас есть какой-либо другой метод автоматического обслуживания, отключите этот процесс.
Далее нам нужно создать новую родительскую таблицу, используя собственное разделение, поскольку вы не можете преобразовать существующую таблицу в родительскую таблицу собственного разделения. Обратите внимание, что в нашем случае исходная таблица имела первичный ключ на col1
. Поскольку col1
не является частью ключа раздела, собственное разделение не позволяет нам объявить его первичным ключом в верхней таблице. Если вам всё ещё нужен первичный ключ, pg_partman предоставляет шаблон таблицы, который вы можете установить, но... Будет сохранена уникальность только для каждого дочернего элемента, аналогично тому, как это работало до нативного режима.
Пожалуйста, обратитесь к разделу «Наследование свойств дочерней таблицы» в файле docs/pg_partman.md, чтобы узнать, какие свойства можно задать для нативной родительской таблицы, а какими нужно управлять через шаблон.
CREATE TABLE partman_test.time_taptest_table_native
(col1 int, col2 text default 'stuff', col3 timestamptz NOT NULL DEFAULT now())
PARTITION BY RANGE (col3);
CREATE INDEX ON partman_test.time_taptest_table_native (col3);
Далее проверьте права собственности и привилегии вашей исходной таблицы и убедитесь, что они существуют в новой родительской таблице. Это обеспечит сохранение доступа к таблице после миграции. По умолчанию при использовании нативного разделения привилегии больше не предоставляются для дочерних таблиц, обеспечивая прямой доступ к ним. Если вы хотите сохранить такое поведение, установите для столбца inherit_privileges
в part_config
(и part_config_sub
, если необходимо) значение true.
\dt partman_test.time_taptest_table
List of relations
Schema | Name | Type | Owner
--------------+--------------------+-------+---------------
partman_test | time_taptest_table | table | partman_owner
(1 row)
\dp+ partman_test.time_taptest_table
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------------+--------------------+-------+-------------------------------------+-------------------+----------
partman_test | time_taptest_table | table | partman_owner=arwdDxt/partman_owner+| |
| | | partman_basic=arwd/partman_owner +| |
| | | testing=r/partman_owner | |
(1 строка)
ALTER TABLE partman_test.time_taptest_table_native OWNER TO partman_owner;
GRANT SELECT, INSERT, UPDATE, DELETE ON partman_test.time_taptest_table_native TO partman_basic;
GRANT SELECT ON partman_test.time_taptest_table_native TO testing;
Лучше всего приостановить всю активность в исходной таблице во время процесса миграции, чтобы избежать проблем. Это можно сделать, временно отменив все разрешения для таблицы или установив эксклюзивную блокировку на родительскую таблицу и выполнив все эти шаги в одной транзакции. Метод транзакций настоятельно рекомендуется по той простой причине, что если вы столкнётесь с какими-либо проблемами до завершения процесса миграции, вы можете просто откатить изменения и вернуться к состоянию, в котором ваша база данных находилась до начала миграции.
BEGIN;
LOCK TABLE partman_test.time_taptest_table IN ACCESS EXCLUSIVE MODE NOWAIT;
Если это секционированная таблица, блокировка верхнего уровня должна блокировать доступ ко всем дочерним таблицам, если вы не используете предложение ONLY.
Первым важным шагом в этом процессе миграции является отмена наследования всех дочерних таблиц от старого родителя. Вы можете использовать запрос, подобный приведённому ниже, для создания операторов ALTER TABLE, отменяющих наследование всех дочерних таблиц от данной родительской таблицы. Лучше всего использовать сгенерированный SQL, чтобы избежать опечаток, особенно при работе с очень большими наборами разделов:
НЕ ВЫПОЛНЯЙТЕ ПОЛУЧЕННЫЕ ЗАЯВЛЕНИЯ ПОКА. Будущий запрос не будет работать, если дочерние таблицы больше не являются частью набора наследования.
SELECT format('ALTER TABLE %s NO INHERIT %s;', inhrelid::regclass, inhparent::regclass)
FROM pg_inherits
WHERE inhparent::regclass = 'partman_test.time_taptest_table'::regclass;
?column?
-----------------------------------------------------------------------------------------------------
ALTER TABLE partman_test.time_taptest_table_p2023_03_26 NO INHERIT partman_test.time_taptest_table;
ALTER TABLE partman_test.time_taptest_table_p2023_03_27 NO INHERIT partman_test.time_taptest_table; 00:00:00-04') TO ('2023-03-30 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_03_30 FOR VALUES FROM ('2023-03-30 00:00:00-04') TO ('2023-03-31 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_03_31 FOR VALUES FROM ('2023-03-31 00:00:00-04') TO ('2023-04-01 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_01 FOR VALUES FROM ('2023-04-01 00:00:00-04') TO ('2023-04-02 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_02 FOR VALUES FROM ('2023-04-02 00:00:00-04') TO ('2023-04-03 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_03 FOR VALUES FROM ('2023-04-03 00:00:00-04') TO ('2023-04-04 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_04 FOR VALUES FROM ('2023-04-04 00:00:00-04') TO ('2023-04-05 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_05 FOR VALUES FROM ('2023-04-05 00:00:00-04') TO ('2023-04-06 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_06 FOR VALUES FROM ('2023-04-06 00:00:00-04') TO ('2023-04-07 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_07 FOR VALUES FROM ('2023-04-07 00:00:00-04') TO ('2023-04-08 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_08 FOR VALUES FROM ('2023-04-08 00:00:00-04') TO ('2023-04-09 00:00:00-04');
ALTER TABLE partman_test.time_taptest_table_native ATTACH PARTITION partman_test.time_taptest_table_p2023_04_09 FOR VALUES FROM ('2023-04-09 00:00:00-04') TO ('2023-04-10 00:00:00-04');
(15 rows)
We can now run these two sets of ALTER TABLE statements to first uninherit them from the old trigger-based parent and attach them to the new native parent. After doing so, the old trigger-based parent should have no longer have children:
\d+ partman_test.time_taptest_table
Table "partman_test.time_taptest_table"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description --------+--------------------------+-----------+----------+---------+----------+-------------+--------------+------------- col1 | integer | | not null | | plain | | | col2 | text | | | | extended | | | col3 | timestamp with time zone | | not null | now() | plain | | | Indexes: "time_taptest_table_pkey" PRIMARY KEY, btree (col1) Triggers: time_taptest_table_part_trig BEFORE INSERT ON partman_test.time_taptest_table FOR EACH ROW EXECUTE FUNCTION partman_test.time_taptest_table_part_trig_func() Access method: heap
And our new native parent should have now adopted all its new children:
\d+ partman_test.time_taptest_table_native Partitioned table "partman_test.time_taptest_table_native" Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description --------+--------------------------+-----------+----------+---------------+----------+-------------+--------------+------------- col1 | integer | | | | plain | | | col2 | text | | | 'stuff'::text | extended | | | col3 | timestamp with time zone | | not null | now()
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )