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

Отказоустойчивость логической репликации

примечание

Эта страница переведена при помощи нейросети GigaChat.

Чтобы позволить узлам-подписчикам продолжать реплицировать данные от узла-издателя даже при его отказе, должен существовать физический резервный узел, соответствующий узлу-издателю. Логические слоты на основном сервере, соответствующие подпискам, могут быть синхронизированы с резервным сервером путем указания failover = true при создании подписок. Подробности подробнее смотрите в разделе «Синхронизация слотов репликации». Включение параметра 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-запрос, чтобы определить, какие слоты синхронизации таблиц должны быть синхронизированы с резервным сервером, который планируем повысить. Запрос нужно выполнить на каждой базе данных, содержащей подписки с возможностью перехода на другой ресурс. Обратите внимание, что слот синхронизации таблицы следует синхронизировать с резервным сервером только в том случае, если копия таблицы завершена (подробнее смотрите раздел «pg_subscription_rel»). Нет необходимости обеспечивать синхронизацию слотов синхронизации таблиц в других сценариях, так как они будут либо удалены, либо повторно созданы на новом первичном сервере в таких случаях.

    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 NOT conflicting) 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)

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

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