29.3. Отработка отказа логической репликации #

Чтобы подписчики могли продолжить репликацию данных с публикующего узла даже в случае отказа узла, необходим физический резервный сервер, связанный с публикующим узлом. Логические слоты главного сервера, соответствующие подпискам, можно синхронизировать с резервным сервером, указывая при создании подписок параметр failover = true. За подробностями обратитесь к Подразделу 47.2.3. Включение параметра failover обеспечивает бесшовный переход таких подписок после повышения резерва. Они могут продолжить получать публикации с нового главного сервера.

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

Чтобы убедиться в готовности резервного сервера к возможному отказу для определённого подписчика, проверьте, что все слоты логической репликации, требующиеся подписчику, синхронизированы с резервным сервером с помощью этих команд:

  1. Чтобы определить, какие слоты логической репликации нужно синхронизировать с резервным сервером, который планируется повысить, выполните приведённый ниже SQL-запрос на подписчике. Этот запрос возвращает слоты, связанные с подписками, на которых включён режим отработки отказа.

    test_sub=# SELECT
                   array_agg(quote_literal(s.subslotname)) AS slots
               FROM  pg_subscription s
               WHERE s.subfailover AND
                     s.subslotname IS NOT NULL;
     slots
    -------
     {'sub1','sub2','sub3'}
    (1 row)
  2. Чтобы определить, какие слоты логической репликации нужно синхронизировать с резервным сервером, который планируется повысить, выполните приведённый ниже SQL-запрос на подписчике. Этот запрос необходимо запустить для каждой базы данных, где есть подписки с включённой отработкой отказа. Обратите внимание, что слот синхронизации таблиц необходимо синхронизировать с резервным сервером, только если завершено создание копии таблицы (см. Раздел 51.55). В других случаях такую синхронизацию проверять не нужно, поскольку слоты либо будут удалены, либо воссозданы на новом главном сервере.

    test_sub=# SELECT
                   array_agg(quote_literal(slot_name)) AS slots
               FROM
               (
                   SELECT CONCAT('pg_', srsubid, '_sync_', srrelid, '_', ctl.system_identifier) AS slot_name
                   FROM pg_control_system() ctl, pg_subscription_rel r, pg_subscription s
                   WHERE r.srsubstate = 'f' AND s.oid = r.srsubid AND s.subfailover
               );
     slots
    -------
     {'pg_16394_sync_16385_7394666715149055164'}
    (1 row)
  3. Проверьте, что указанные слоты логической репликации существуют на резервном сервере и готовы к отработке отказа.

    test_standby=# SELECT slot_name, (synced AND NOT temporary AND invalidation_reason IS NULL) AS failover_ready
                   FROM pg_replication_slots
                   WHERE slot_name IN
                       ('sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164');
      slot_name                                 | failover_ready
    --------------------------------------------+----------------
      sub1                                      | t
      sub2                                      | t
      sub3                                      | t
      pg_16394_sync_16385_7394666715149055164   | t
    (4 rows)

Если слоты присутствуют на резервном сервере и готовы к отработке отказа (запрос выше вернул true для failover_ready), то существующие подписки продолжат работать с новым главным сервером.

Первые два шага вышеуказанной процедуры выполняются подписчиком PostgreSQL. Рекомендуется пройти эту инструкцию на каждом узле подписчика, который будет обслуживаться назначенным резервным сервером после переключения, что сформирует полный список слотов репликации. Этот список можно проверить на третьем шаге, чтобы убедиться в готовности аварийного переключения. Подписчики, не относящиеся к PostgreSQL, могут использовать другие методы, чтобы определить, какие слоты репликации используется в их подписках.

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

/* primary # */ SELECT array_agg(quote_literal(r.slot_name)) AS slots
               FROM pg_replication_slots r
               WHERE r.failover AND NOT r.temporary;
 slots
-------
 {'sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164'}
(1 row)