28.13. Обновление#

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.

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

    pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile
    

  10. На node2 создайте все таблицы, которые были созданы на обновлённом сервере публикующего сервера node1 в период между Step 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;
    

Примечание

В описанных выше шагах сначала обновляется публикующий сервер, затем подписчик. В качестве альтернативы пользователь может выполнить аналогичные шаги, чтобы сначала обновить подписчика, а затем публикующий сервер.

28.13.3.2. Шаги по обновлению кластера каскадной логической репликации #

Допустим, у нас есть конфигурация с каскадной логической репликацией 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 в период между Step 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;
    

  13. Обновите публикации подписки node2 с помощью ALTER SUBSCRIPTION ... REFRESH PUBLICATION, например:

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

  14. Остановите сервер на node3, например:

    pg_ctl -D /opt/PostgreSQL/data3 stop
    

  15. Инициализируйте экземпляр data3_upgraded, используя более новую версию.

  16. Обновите сервер 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"
    

  17. Запустите обновлённый сервер на node3, например:

    pg_ctl -D /opt/PostgreSQL/data3_upgraded start -l logfile
    

  18. На node3 создайте все таблицы, которые были созданы в обновлённом node2 в период между Step 6 и настоящим моментом, например:

    /* node3 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
    

  19. Включите все подписки на node3, которые получают изменения от node2, с помощью ALTER SUBSCRIPTION ... ENABLE, например:

    /* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 ENABLE;
    

  20. Обновите публикации подписки 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.

  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 в период между Step 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 между Step 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;