Перейти к основному содержимому

Обновление

Миграция кластеров логической репликации возможна только в том случае, если все участники старых кластеров логической репликации имеют версию 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 должен быть настроен на значение, большее или равное количеству подписок, присутствующих в старом кластере.

Обновление кластеров логической репликации

Во время обновления подписчика на издателе могут выполняться операции записи. Эти изменения будут реплицированы на подписчика после завершения обновления подписчика.

примечание

Ограничения логической репликации применяются также к обновлению кластеров логической репликации.

Предварительные условия обновления издателя применяются также к обновлению кластеров логической репликации. Подробности смотрите в разделе «Шаги по обновлению двух узлового кластера логической репликации».

Предварительные условия обновления подписчика применяются также к обновлению кластеров логической репликации. Подробности смотрите в разделе «Шаги по обновлению кластера с каскадной логической репликацией».

warning

Обновление кластера логической репликации требует выполнения нескольких шагов на различных узлах. Поскольку не все операции являются транзакционными, пользователю рекомендуется создавать резервные копии, как описано в разделе «Создание базовой резервной копии».

Ниже подробно описаны шаги по обновлению следующих кластеров логической репликации:

Шаги по обновлению двух узлового кластера логической репликации

Предположим, что издатель находится на node1, а подписчик — на node2. У node2, являющегося подписчиком, есть подписка sub1_node1_node2, которая отслеживает изменения с node1.

  1. Отключите все подписки на node2, которые отслеживают изменения с node1, используя команду ALTER SUBSCRIPTION ... DISABLE, например:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
  2. Остановите сервер издателя на node1, например:

    pg_ctl -D /opt/PostgreSQL/data1 stop
  3. Инициализируйте экземпляр data1_upgraded, используя необходимую более новую версию.

  4. Обновите сервер издателя на 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"
  5. Запустите обновленный сервер издателя на node1, например:

    pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
  6. Остановите сервер подписчика на node2, например:

    pg_ctl -D /opt/PostgreSQL/data2 stop
  7. Инициализируйте экземпляр data2_upgraded, используя необходимую более новую версию.

  8. Обновите сервер на 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"
  9. Запустите обновленный сервер подписчика на nodenode2, например:

    pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
  10. На node2 создайте все таблицы, которые были созданы на обновленном сервере издателя node1 между шагом 1 и текущим моментом, например:

    /* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
  11. Включите все подписки на node2, которые подписываются на изменения с node1, используя ALTER SUBSCRIPTION ... ENABLE, например:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
  12. Обновите публикации подписки 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.

  1. Отключите все подписки на node2, которые подписываются на изменения от node1, используя команду ALTER SUBSCRIPTION ... DISABLE, например:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
  2. Остановите сервер на node1, например:

    pg_ctl -D /opt/PostgreSQL/data1 stop
  3. Инициализируйте экземпляр data1_upgraded, используя необходимую более новую версию.

  4. Обновите сервер на 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"
  5. Запустите обновленный сервер на node1, например:

    pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
  6. Отключите все подписки на node3, которые подписываются на изменения с node2, используя ALTER SUBSCRIPTION ... DISABLE, например:

    /* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 DISABLE;
  7. Остановите сервер на node2, например:

    pg_ctl -D /opt/PostgreSQL/data2 stop
  8. Инициализируйте экземпляр data2_upgraded, используя необходимую более новую версию.

  9. Обновите сервер на 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"
  10. Запустите обновленный сервер на node2, например:

    pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
  11. На node2 создайте все таблицы, которые были созданы на обновленном сервере издателя node1 между шагом 1 и текущим моментом, например:

    /* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
  12. Включите все подписки на node2, которые подписываются на изменения с node1, используя ALTER SUBSCRIPTION ... ENABLE, например:

/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
  1. Обновите публикации подписки на node2, используя ALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
  2. Остановите сервер на node3, например:

    pg_ctl -D /opt/PostgreSQL/data3 stop
  3. Инициализируйте экземпляр data3_upgraded, используя необходимую более новую версию.

  4. Обновите сервер на 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"
  5. Запустите обновленный сервер на node3, например:

    pg_ctl -D /opt/PostgreSQL/data3_upgraded start -l logfile
  6. На node3 создайте все таблицы, которые были созданы на обновленном node2 между шагом 6 и текущим моментом, например:

    /* node3 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
  7. Включите все подписки на node3, которые подписываются на изменения с node2, используя команду ALTER SUBSCRIPTION ... ENABLE, например:

    /* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 ENABLE;
  8. Обновите публикации подписки на 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.

  1. Отключите все подписки на node2, которые подписываются на изменения от node1, используя команду ALTER SUBSCRIPTION ... DISABLE, например:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
  2. Остановите сервер на node1, например:

    pg_ctl -D /opt/PostgreSQL/data1 stop
  3. Инициализируйте экземпляр data1_upgraded, используя необходимую более новую версию.

  4. Обновите сервер на 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"
  5. Запустите обновленный сервер на node1, например:

    pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile
  6. Включите все подписки на node2, которые подписываются на изменения с node1, используя ALTER SUBSCRIPTION ... ENABLE, например:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
  7. На node1 создайте все таблицы, созданные на node2 между шагом 1 и текущим моментом, например:

    /* node1 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
  8. Обновите публикации подписки на node1, чтобы скопировать исходные данные таблиц с node2, используя ALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 REFRESH PUBLICATION;
  9. Отключите все подписки на node1, которые подписываются на изменения с node2, используя ALTER SUBSCRIPTION ... DISABLE, например:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 DISABLE;
  10. Остановите сервер на node2, например:

    pg_ctl -D /opt/PostgreSQL/data2 stop
  11. Инициализируйте экземпляр data2_upgraded, используя необходимую более новую версию.

  12. Обновите сервер на 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"
  13. Запустите обновленный сервер на node2, например:

    pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
  14. Включите все подписки на node1, которые подписываются на изменения с node2, используя ALTER SUBSCRIPTION ... ENABLE, например:

    /* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 ENABLE;
  15. На node2 создайте все таблицы, созданные на обновленном node1 между шагом 9 и текущим моментом, например:

    /* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
  16. Обновите публикации подписки node2, чтобы скопировать исходные данные таблиц с node1, используя ALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:

    /* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;