30.13. Обновление #
Миграция кластера логической репликации возможна только в том случае, если все члены старого кластера логической репликации находятся на версии 17.0 и выше.
30.13.1. Подготовиться к обновлению публикующего сервера #
Программа pg_upgrade пытается мигрировать логические слоты. Это устраняет необходимость определять те же логические слоты на новом публикующем сервере вручную. Миграция логических слотов поддерживается только в случае, если старый кластер версии 17.0 или выше. Логические слоты на кластерах до версии 17.0 будут игнорироваться без уведомления.
Прежде чем начать обновление публикующего кластера, убедитесь, что подписка временно отключена, выполнив команду ALTER SUBSCRIPTION ... DISABLE. Включите подписку после завершения обновления.
Необходимо выполнить ряд предварительных требований, чтобы программа pg_upgrade смогла обновить логические слоты. В противном случае будет выдаваться ошибка.
В новом кластере
wal_levelдолжен иметь значениеlogical.Для нового кластера у параметра
max_replication_slotsдолжно быть установлено значение не меньше количества слотов на старом кластере или равное ему.Модули вывода, на которые ссылаются слоты на старом кластере, должны быть установлены в каталоге с исполняемыми файлами новой версии PostgreSQL.
В старом кластере все транзакции и сообщения логического декодирования передавались подписчикам.
Все слоты на старом кластере должны быть доступны для использование, то есть не должно быть слотов, у которых для представления pg_replication_slots.
conflictingне задано значениеtrue.В новом кластере не должно быть постоянных логических слотов, т. е. не должно быть слотов, в которых pg_replication_slots.
temporaryимеет значениеfalse.
30.13.2. Подготовиться к обновлению ведомых серверов #
Установите для нового подписчика subscriber configurations.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должен иметь значение, большее или равное числу подписок в старом.
30.13.3. Обновление кластеров логической репликации #
При обновлении подписчика можно выполнять операции записи на публикующем сервере. Такие изменения реплицируются на подписчика по завершении его обновления.
Примечание
Ограничения логической репликации применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Разделе 30.8.
Предварительные условия обновления публикующего сервера применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Подразделе 30.13.1.
Предварительные условия обновления подписчика применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Подразделе 30.13.2.
Предупреждение
Чтобы обновить кластер логической репликации, необходимо выполнить несколько действий на разных узлах. Поскольку не все операции являются транзакционными, пользователям рекомендуется делать резервные копии по инструкции, описанной в Подразделе 25.3.2.
Шаги по обновлению следующих кластеров логической репликации представлены ниже:
Следуйте инструкции в Подразделе 30.13.3.1, чтобы обновить кластер логической репликации с двумя узлами.
Следуйте инструкции в Подразделе 30.13.3.2, чтобы обновить кластер каскадной логической репликации.
Следуйте инструкции в Подразделе 30.13.3.3, чтобы обновить кластер двунаправленной логической репликации с двумя узлами.
30.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;
Примечание
В описанных выше шагах первым обновляется публикующей сервер, а после него — подписчик. Как вариант, можно воспользоваться шагами и сначала обновить подписчика, а затем публикующий сервер.
30.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;
30.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;