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;