Обновление
Миграция кластеров логической репликации возможна только в том случае, если все участники старых кластеров логической репликации имеют версию 17.0 или выше.
Подготовка к обновлению издателя
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.
Подготовка к обновлению подписчиков
Настройте конфигурацию подписчика в новом кластере. 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должен быть настроен на значение, большее или равное количеству подписок, присутствующих в старом кластере.
Обновление кластеров логической репликации
Во время обновления подписчика на издателе могут выполняться операции записи. Эти изменения будут реплицированы на подписчика после завершения обновления подписчика.
Ограничения логической репликации применяются также к обновлению кластеров логической репликации.
Предварительные условия обновления издателя применяются также к обновлению кластеров логической репликации. Подробности смотрите в разделе «Шаги по обновлению двух узлового кластера логической репликации».
Предварительные условия обновления подписчика применяются также к обновлению кластеров логической репликации. Подробности смотрите в разделе «Шаги по обновлению кластера с каскадной логической репликацией».
Обновление кластера логической репликации требует выполнения нескольких шагов на различных узлах. Поскольку не все операции являются транзакционными, пользователю рекомендуется создавать резервные копии, как описано в разделе «Создание базовой резервной копии».
Ниже подробно описаны шаги по обновлению следующих кластеров логической репликации:
- Для обновления двух узлового кластера логической репликации выполните действия, указанные в разделе «Шаги по обновлению двух узлового кластера логической репликации».
- Для обновления каскадного кластера логической репликации выполните действия, указанные в разделе «Шаги по обновлению кластера с каскадной логической репликацией».
- Для обновления двух узлового кластера циклической логической репликации выполните действия, указанные в разделе «Шаги по обновлению кластера с циклической логической репликацией на двух узлах».
Шаги по обновлению двух узлового кластера логической репликации
Предположим, что издатель находится на 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, используя необходимую более новую версию. -
Обновите сервер на nodeподписчика
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" -
Запустите обновленный сервер подписчика на node
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;
В описанных выше шагах сначала обновляется издатель, а затем подписчик. В качестве альтернативы пользователь может использовать аналогичные шаги для обновления сначала подписчика, а затем издателя.
Шаги по обновлению кластера с каскадной логической репликацией
Предположим, имеется конфигурация каскадной логической репликации: 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;
Шаги по обновлению кластера с циклической логической репликацией на двух узлах
Предположим, имеется конфигурация циклической логической репликации: 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;