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

Миграция кластера логической репликации возможна только в том случае, если все члены старого кластера логической репликации находятся на версии 17.0 и выше.

30.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.

30.13.2. Подготовиться к обновлению ведомых серверов #

Установите для нового подписчика subscriber configurations.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 должен иметь значение, большее или равное числу подписок в старом.

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

При обновлении подписчика можно выполнять операции записи на публикующем сервере. Такие изменения реплицируются на подписчика по завершении его обновления.

Примечание

Ограничения логической репликации применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Разделе 30.8.

Предварительные условия обновления публикующего сервера применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Подразделе 30.13.1.

Предварительные условия обновления подписчика применяются к процессу обновления кластера логической репликации. Более подробная информация описана в Подразделе 30.13.2.

Предупреждение

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

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

  • Следуйте инструкции в Подразделе 30.13.3.1, чтобы обновить кластер логической репликации с двумя узлами.

  • Следуйте инструкции в Подразделе 30.13.3.2, чтобы обновить кластер каскадной логической репликации.

  • Следуйте инструкции в Подразделе 30.13.3.3, чтобы обновить кластер двунаправленной логической репликации с двумя узлами.

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

Примечание

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

30.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 в промежуток времени между Шаг 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 в промежуток времени между Шаг 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;

30.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 в промежуток времени между Шаг 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;