28.13. Обновление#
28.13. Обновление #
Миграция кластеров логической репликации возможна только в том случае, если все участники старых кластеров логической репликации имеют версию 17.0 или новее.
28.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.
28.13.2. Подготовка к обновлению подписчика #
Настройте параметры подписчика на новом подписчике. pg_upgrade попытается перенести зависимости подписчиков, включая информацию о таблицах подписки, содержащуюся в системном каталоге pg_subscription_rel, а также источник репликации подписки. Это позволяет логической репликации на новом подписчике продолжить работу с того места, на котором остановился старый подписчик. Перенос зависимостей подписчиков поддерживается только если версия старая кластера — 17.0 или новее. Зависимости подписки в кластерах до версии 17.0 будут проигнорированы без предупреждения.
Существуют некоторые предварительные условия для того, чтобы программа pg_upgrade мог обновлять подписки. Если эти условия не выполнены, будет выдана ошибка.
Все таблицы подписки на старом подписчике должны находиться в состоянии
i(инициализация) илиr(готовность). Это можно проверить с помощью pg_subscription_rel.srsubstate.Запись об источнике репликации, соответствующая каждой из подписок, должна существовать в старом кластере. Это можно проверить, просмотрев системные таблицы pg_subscription и pg_replication_origin.
В новом кластере параметр
max_active_replication_originsдолжен иметь значение, которое больше или равно количеству подписок, присутствующих в старом кластере.
28.13.3. Обновление кластеров логической репликации #
Во время обновления подписчика операции записи могут выполняться на публикующем сервере. Эти изменения будут реплицированы на подписчика после завершения его обновления.
Примечание
Ограничения логической репликации применяются также и к обновлениям кластера с использованием логической репликации. См. Раздел 28.8 для получения более подробной информации.
Предварительные условия для обновлению публикующего сервера применимы также к обновлениям кластера логической репликации. См. Раздел 28.13.1 для получения более подробной информации.
Предварительные условия для обновления подписчика применимы также к обновлениям кластера логической репликации. См. Раздел 28.13.2 для получения более подробной информации.
Предупреждение
Обновление кластера логической репликации требует выполнения нескольких шагов на разных узлах. Поскольку не все операции являются транзакционными, рекомендуется создавать резервные копии, как описано в Раздел 24.3.2.
Детальные шаги по обновлению следующих кластеров логической репликации приведены ниже:
Выполните шаги, указанные в Раздел 28.13.3.1, чтобы обновить кластер логической репликации с двумя узлами.
Выполните шаги, указанные в Раздел 28.13.3.2, чтобы обновить кластер каскадной логической репликации.
Выполните шаги, указанные в Раздел 28.13.3.3 для обновления кластера двунаправленной логической репликации с двумя узлами.
28.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создайте все таблицы, которые были созданы на обновлённом сервере публикующего сервераnode1в период между Step 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;
Примечание
В описанных выше шагах сначала обновляется публикующий сервер, затем подписчик. В качестве альтернативы пользователь может выполнить аналогичные шаги, чтобы сначала обновить подписчика, а затем публикующий сервер.
28.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в период между Step 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в период между Step 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;
28.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в период между Step 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между Step 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;