29.13. Обновление #
Миграция кластера логической репликации возможна только в том случае, если все члены старого кластера логической репликации находятся на версии 17.0 и выше.
29.13.1. Подготовка обновления публикующего узла #
pg_upgrade пытается мигрировать логические слоты. Это позволяет не определять эти же слоты вручную на новом публикующем узле. Миграция логических слотов поддерживается, только если старый кластер находится на версии 17 или выше. Логические слоты на кластере до версии 17 игнорируются без предупреждения.
Перед обновлением версии кластера публикующего сервера убедитесь, что подписка временно отключена, выполнив команду ALTER SUBSCRIPTION ... DISABLE. Заново включите подписку после обновления.
У pg_upgrade есть несколько предварительных условий, при которых возможно обновление логических слотов. Их несоблюдение приведёт к ошибке.
В новом кластере
wal_levelдолжен иметь значениеlogical.В новом кластере параметр
max_replication_slotsдолжен иметь значение, большее или равное числу слотов в старом кластере.Модули вывода, на которые ссылаются слоты на старом кластере, должны быть установлены в каталоге с исполняемыми файлами новой версии PostgreSQL.
В старом кластере все транзакции и сообщения логического декодирования передавались подписчикам.
Все слоты в старом кластере должны использоваться, т. е. не должно быть слотов, в которых pg_replication_slots.
conflictingне имеет значениеtrue.В новом кластере не должно быть постоянных логических слотов, т. е. не должно быть слотов, в которых pg_replication_slots.
temporaryимеет значениеfalse.
29.13.2. Подготовка к обновлению подписчиков #
Задайте параметры конфигурации нового подписчика. pg_upgrade предпримет попытку мигрировать зависимости подписчиков, которые включают информацию о таблицах подписчиков, находящуюся в системном каталоге pg_subscription_rel, а также источник репликации подписчика. Благодаря этому логическая репликация на новом подписчике продолжится с момента, где она остановилась на старом подписчике. Миграция зависимостей подписчиков поддерживается, только если старый кластер версии 17.0 или выше. Зависимости подписчиков на кластерах до версии 17.0 игнорируются без предупреждения.
У pg_upgrade есть несколько предварительных условий, при которых возможно обновление подписок. Их несоблюдение приведёт к ошибке.
Все таблицы подписки в старом подписчике должны быть в состоянии
i(initialize, инициализация) илиr(ready, готовность). Это можно проверить с помощью pg_subscription_rel.srsubstate.В старом кластере должна быть запись об источнике репликации для каждой из подписок. Это можно проверить в системных таблицах pg_subscription и pg_replication_origin.
В новом кластере параметр
max_active_replication_originsдолжен иметь значение, большее или равное числу подписок в старом.
29.13.3. Обновление кластеров логической репликации #
При обновлении подписчика можно выполнять операции записи на публикующем сервере. Такие изменения реплицируются на подписчика по завершении его обновления.
Примечание
Ограничения логической репликации применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Разделе 29.8.
Предварительные условия обновления публикующего сервера применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Подразделе 29.13.1.
Предварительные условия обновления подписчика применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Подразделе 29.13.2.
Предупреждение
Чтобы обновить кластер логической репликации, необходимо выполнить несколько действий на разных узлах. Поскольку не все операции являются транзакционными, пользователям рекомендуется делать резервные копии по инструкции, описанной в Подразделе 25.3.2.
Шаги по обновлению следующих кластеров логической репликации представлены ниже:
Следуйте инструкции в Подразделе 29.13.3.1, чтобы обновить кластер логической репликации с двумя узлами.
Следуйте инструкции в Подразделе 29.13.3.2, чтобы обновить кластер каскадной логической репликации.
Следуйте инструкции в Подразделе 29.13.3.3, чтобы обновить кластер двунаправленной логической репликации с двумя узлами.
29.13.3.1. Шаги по обновлению кластера логической репликации с двумя узлами #
Предположим, что публикующий сервер — node1, а подписчик — node2. У подписчика node2 есть подписка sub1_node1_node2 на изменения на node1.
Отключите на
node2все подписки, которые подписаны на измененияnode1, воспользовавшись командойALTER SUBSCRIPTION ... DISABLE, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
Остановите публикующий сервер на узле
node1, например:pg_ctl -D /opt/PostgreSQL/data1 stop
Инициализируйте экземпляр
data1_upgraded, воспользовавшись более новой версией.Обновите публикующий сервер узла
node1до новой версии, например:pg_upgrade --old-datadir "/opt/PostgreSQL/postgres/17/data1" --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded" --old-bindir "/opt/PostgreSQL/postgres/17/bin" --new-bindir "/opt/PostgreSQL/postgres/18/bin"Запустите обновлённый публикующий сервер на узле
node1, например:pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
Остановите сервер подписчика на узле
node2, например:pg_ctl -D /opt/PostgreSQL/data2 stop
Инициализируйте экземпляр
data2_upgraded, воспользовавшись более новой версией.Обновите сервер узла
node2подписчика до новой версии, например:pg_upgrade --old-datadir "/opt/PostgreSQL/postgres/17/data2" --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded" --old-bindir "/opt/PostgreSQL/postgres/17/bin" --new-bindir "/opt/PostgreSQL/postgres/18/bin"Запустите обновлённый сервер подписчика на узле
node2, например:pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
На узле
node2создайте таблицы, созданные на обновлённом сервере публикующего узлаnode2в промежуток времени между Шаг 1 и настоящим моментом, например:/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
Включите на узле
node2все подписки, которые подписаны на измененияnode1, воспользовавшись командойALTER SUBSCRIPTION ... ENABLE, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
Обновите публикации подписки узла
node2, воспользовашись командойALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
Примечание
В описанных выше шагах первым обновляется публикующей сервер, а после него — подписчик. Как вариант, можно воспользоваться шагами и сначала обновить подписчика, а затем публикующий сервер.
29.13.3.2. Шаги по обновлению кластера каскадной логической репликации #
Предположим, у нас есть конфигурация с каскадной логической репликацией node1->node2->node3. В этом случае node2 подписывается на изменения node1, а node3 — на изменения node2. У node2 есть подписка sub1_node1_node2, то есть подписка на изменения node1. Уnode3 есть подписка sub1_node2_node3, то есть подписка на изменения node2.
Отключите на
node2все подписки, которые подписаны на измененияnode1, воспользовавшись командойALTER SUBSCRIPTION ... DISABLE, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
Остановите сервер на узле
node1, например:pg_ctl -D /opt/PostgreSQL/data1 stop
Инициализируйте экземпляр
data1_upgraded, воспользовавшись более новой версией.Обновите сервер узла
node1до новой версии, например:pg_upgrade --old-datadir "/opt/PostgreSQL/postgres/17/data1" --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded" --old-bindir "/opt/PostgreSQL/postgres/17/bin" --new-bindir "/opt/PostgreSQL/postgres/18/bin"Запустите обновлённый сервер на узле
node1, например:pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
Отключите на
node3все подписки, которые подписаны на измененияnode2, воспользовавшись командойALTER SUBSCRIPTION ... DISABLE, например:/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 DISABLE;
Остановите сервер на узле
node2, например:pg_ctl -D /opt/PostgreSQL/data2 stop
Инициализируйте экземпляр
data2_upgraded, воспользовавшись более новой версией.Обновите сервер узла
node2до новой версии, например:pg_upgrade --old-datadir "/opt/PostgreSQL/postgres/17/data2" --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded" --old-bindir "/opt/PostgreSQL/postgres/17/bin" --new-bindir "/opt/PostgreSQL/postgres/18/bin"Запустите обновлённый сервер на узле
node2, например:pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
На узле
node2создайте таблицы, созданные на обновлённом сервере публикующего узлаnode1в промежуток времени между Шаг 1 и настоящим моментом, например:/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
Включите на узле
node2все подписки, которые подписаны на измененияnode1, воспользовавшись командойALTER SUBSCRIPTION ... ENABLE, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
Обновите публикации подписки узла
node2, воспользовашись командойALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
Остановите сервер на узле
node3, например:pg_ctl -D /opt/PostgreSQL/data3 stop
Инициализируйте экземпляр
data3_upgraded, воспользовавшись более новой версией.Обновите сервер узла
node3до новой версии, например:pg_upgrade --old-datadir "/opt/PostgreSQL/postgres/17/data3" --new-datadir "/opt/PostgreSQL/postgres/18/data3_upgraded" --old-bindir "/opt/PostgreSQL/postgres/17/bin" --new-bindir "/opt/PostgreSQL/postgres/18/bin"Запустите обновленный сервер на узле
node3, например:pg_ctl -D /opt/PostgreSQL/data3_upgraded start -l logfile
На узле
node3создайте таблицы, созданные на обновлённом узлеnode2в промежуток времени между Шаг 6 и настоящим моментом, например:/* node3 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
Включите на узле
node3все подписки, которые подписаны на измененияnode2, воспользовавшись командойALTER SUBSCRIPTION ... ENABLE, например:/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 ENABLE;
Обновите публикации подписки узла
node3, воспользовавшись командойALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 REFRESH PUBLICATION;
29.13.3.3. Шаги по обновлению кластера двунаправленной логической репликации с двумя узлами #
Предположим, у нас есть конфигурация с двунаправленной логической репликацией node1->node2 и node2->node1. В таком случае node2 подписывается на изменения node1, а node1 подписывается на изменения node2. У node1 есть подписка sub1_node2_node1, которая подписывает на изменения node2. У node2 есть подписка sub1_node1_node2, которая подписывает на изменения node1.
Отключите на
node2все подписки, которые подписаны на измененияnode1, воспользовавшись командойALTER SUBSCRIPTION ... DISABLE, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
Остановите сервер на узле
node1, например:pg_ctl -D /opt/PostgreSQL/data1 stop
Инициализируйте экземпляр
data1_upgraded, воспользовавшись более новой версией.Обновите сервер узла
node1до новой версии, например:pg_upgrade --old-datadir "/opt/PostgreSQL/postgres/17/data1" --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded" --old-bindir "/opt/PostgreSQL/postgres/17/bin" --new-bindir "/opt/PostgreSQL/postgres/18/bin"Запустите обновлённый сервер на узле
node1, например:pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
Включите на узле
node2все подписки, которые подписаны на измененияnode1, воспользовавшись командойALTER SUBSCRIPTION ... ENABLE, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
На узле
node1создайте таблицы, созданные наnode2в промежуток времени между Шаг 1 и настоящим моментом, например:/* node1 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
Обновите публикации подписки узла
node1, чтобы скопировать информацию об исходной таблице изnode2, воспользовавшись командойALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 REFRESH PUBLICATION;
Отключите на
node1все подписки, которые подписаны на измененияnode2, воспользовавшись командойALTER SUBSCRIPTION ... DISABLE, например:/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 DISABLE;
Остановите сервер на узле
node2, например:pg_ctl -D /opt/PostgreSQL/data2 stop
Инициализируйте экземпляр
data2_upgraded, воспользовавшись более новой версией.Обновите сервер узла
node2до новой версии, например:pg_upgrade --old-datadir "/opt/PostgreSQL/postgres/17/data2" --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded" --old-bindir "/opt/PostgreSQL/postgres/17/bin" --new-bindir "/opt/PostgreSQL/postgres/18/bin"Запустите обновлённый сервер на узле
node2, например:pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
Включите на
node1все подписки, которые подписаны на измененияnode2, воспользовавшись командойALTER SUBSCRIPTION ... ENABLE, например:/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 ENABLE;
На узле
node2создайте таблицы, созданные на обновлённом узлеnode1в промежуток времени между Шаг 9 и настоящим моментом, например:/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
Обновите публикации подписки
node2, чтобы скопировать информацию об исходной таблице изnode1, воспользовавшись командойALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;