1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-Pg-Partman

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
migrate_to_declarative.md 15 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 21:50 171ec7b

Миграция с триггерного разделения на декларативное разделение в 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_configpart_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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-Pg-Partman.git
git@api.gitlife.ru:oschina-mirror/mirrors-Pg-Partman.git
oschina-mirror
mirrors-Pg-Partman
mirrors-Pg-Partman
master