Направление PostgreeSQL  
  Репликации БД - аналог логических и физических стэндбаев  


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

Авторская площадка "Наши орбиты" состоит из ряда тематических подразделов, являющихся моими лабораторными дневниками, содержащими записи за разное, иногда продолжительно отличающееся, время. Эти материалы призваны рассказать о прошедшем опыте, они никого ни к чему не призывают и совершенно не обязательно могут быть применимы кем-то ещё. Это только лишь истории о прошлом

Вводные по физическим стэндбаям в PostgreSQL

То, что в Оракле называется физическими стэндбаями, поддерживается и в Потсгрисе. Механизм в целом похожий - идёт копирование оператьивных журналов, и они накатываются на базе (а в терминах постгриса - кластере) стэндбае. После создания копии кластера, если в него положить файл standby,signal и стартовать кластер, происходит попытка подката журналов сначала командой из параметра restore_command, потом - настроенным, если настроенным, механизмом потоковой репликациеи. По исчерпанию журналов такие попытки продолжаются - сначала restore_command, потом потоковая репликация, если настроена

Из этого следует, что организовать физический стэндбай кластера можно несколькими способами. Или обеспечить стэндбаю пополняемый источник архивных журналов, которые по мере появления новых журналов будут накатываться на стэндбай в бесконечном режиме, или же настроить потоковую репликацию, когда стэндбай сам будет вытягивать архивные журналы с мастера. Или же настроить оба механизма, и тогда стэндбай (он же кластер физической реплики) будет автоматом брать журналы там, где они будут доступны. Если организовывать источник архивных журналов снаружи, то его тоже можно сделать или отдельной утилитой потоковой репликации pg_reveivewal, или просто раздать по сети каталог с архивными журналами мастер - сервера. Стэндбай также может архивировать себе получаемые журналы после применения, если выставить archive_mode = always. Таким образом есть большая гибкость в создаваемой конфигурации с мастером и физической репликой, и у каждого варианта есть свои плюсы и минусы

При необходимости переключения в режим нового праймари (мастера) необходимо отработать pg_ctl promote или pg_promote()

Установка СУБД

Полностью сдублировать окружение с мастера - операционку, версию СУБД, расширение. Оптимизировать или скопировать параметры

Создание реплики кластера БД

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

-- ----------------------------------------------------
-- на мастере создать  репликационный слот
-- ----------------------------------------------------
select pg_create_physical_replication_slot('имя_слота_стэндбая') ;
select * from pg_replication_slots ;
-- проверить параметры wal_level = replica, max_wal_senders больше 2 (обычно ставят от 10 - бэкапы, другие стэндбаи и т.п.)
-- выдать раррешения на удалённый доступ репликации в hba.conf

-- ----------------------------------------------------
-- на сервере стэндбая создать реплику под стэндбай
-- ----------------------------------------------------
-- или с помощью pg_basebackup
pg_basebackup -U <имя_пользователя> -h <IP-сервера> -p <порт> -R --slot=<имя_репликационного_слота_мастера> \
   -D <путь к каталогу, в который восстанавливать реплику>

-- или с помощью pg_probackup
pg_probackup restore -i <имя_бэкапного_инстанса> -D <каталог для восстановления> -R --primary-conninfo="host=<IP_мастера> \
   port=<порт_мастера> user=<имя_пользователя, например, backup> password=<пароль_пользователя>" -S <имя_репликационного_слота_мастера> \
   -j <параллелизм>

-- ----------------------------------------------------
-- на сервере стэндбая стартовать стэндбай штатно
-- ----------------------------------------------------

Обе две команды запишут в восстановленные вместе с кластером БД файлы конфигурации параметры, отвечающие за потоковую репликацию журналов с мастера на реплику - primary_conninfo и primary_slot_name. Их можно править в будущем, берутся они из аргументов запуска самих команд создания реплики. Полезно также сразу включить параметр hot_standby_feedback = 'on', понимая, ято это даст возможность длительного чтения на стэндбае без конфликтов восстановления ценой возможного временного раздувания соответствующих таблиц на мастере. Также, для стэндбая через внешний перенос архивных журналов на мастере полезно выставить приличное значение параметра wal_keep_size, чтобы журналы не удалялись быстро. Хотя по мне проще делать перенос уже именно архивных журналов. Ещё при множественных стэндбаях, каждый из которых может быть повышен до мастера, нужна опция recovery_target_timelime = 'latest' (но это как раз значение по умолчанию)

При создании реплики отличие между использованием pg_basebackup и pg_probackup заключается в том, что первая утилита сделает базу с продуктовой, а вторая - восстановит БД и бэкапа. При восстановлении из бэкапа журналы фактически работающей БД мастера могут уйти далеко вперед, и стэндбай не стартует по причине недоступности старых журналов. Такие недостающие журналы можно положить из бэкапа в каталог, который в дальнейшем будет указан в команде restore_command стэндбая. При старте стэндбая недостающие журналы будут искаться командой из параметра restore_command. В случае успеха после их подката стартует уже потоковая репликация по ранее созданному слоту. Также pg_probackup умеет работать в многопоточном режиме, что может резко сократить время создания реплики. Пример параметра restore_command:

restore_command = '[ -f /var/lib/pgsql/tmp_back/archive/%f ] && cp /var/lib/pgsql/tmp_back/archive/%f  %p'

Дополнительная репликация архивных журналов

Эта история имеет развитие, когда для обеспечения стэндбаю журналов возможно настроить альтернативным механизм их репликации на стэндбай. Сам стэндбай, будучи стартован и открыт на чтение, после применения не архивировирует полученные с мастера журналы, если archive_mode не установлен в значение always. С другой стороны хорошим тоном является дублирование конфигураций. Это значит, что отдельная ёмкость для хранения архивных журналов у вас предусмотрена и на стэндбае, аналогично праймари, т.е. мастеру. Вот в эту ёмкость можно привозить копии архивных журналов. Для этого можно создать отдельный репликационный слот, и иcпользовать штатную утилиту pg_receivewal. Например, так:

export PG_PASSWORD=<пароль_пользователя>
# создать слот - один раз запускается
pg_receivewal -h <IP_хоста> -p <порт> -U <имя_пользователя> --create-slot --slot=arch_log_slot
# стартовать потоковую репликацию журналов, стартовать каждый раз при рестарте сервера
pg_receivewal -h <IP_хоста> -p <порт> -U <имя_пользователя> -D /var/lib/pgsql/tmp_back/arch_log_02 --slot=arch_log_slot

Обязательно в этом сценарии указать стэндбаю корректную команду restore_command, как рассматривалось выше. Положительное значение выполнения она должна выдавать только при корректном поиске и копировании по запросу СУБД соответствующего файла журнала

Насколько такая подстраховка для стэндбая нужна - это вопрос спорный. Журналы в обоих случаях приходят пусть с разных слотов, но единым механизмом репликации. А значит не будут удалены на источнике, пока не будут отданы приёмнику. Но сама возможность в документах упоминается. Например, это может потребоваться для втягивания журналов при длительных отключениях стэндбая с его репликационным механизмом. Или если всё же делать стэндбай без потоковой репликации - накатом вновь появляющихся в каталоге журналов. На мой взгляд здесь более востребовано предоставление доступа к бэкапу архивных журналов, делаемых с мастера, на серверах стэндбаев. Однако возможна своя засада - задержка в переносе бэкапных копий с мастера на бэкапные разделы ... Настраивать и потоковый стэндбай, и потоковое дублирование архивных журналов на тот же сервер - значит в два раза повышать нагрузку на сеть. А ведь можно при потоковом стэндбае выставить archime_mode = always, и стэндбай сам будет архивировать примененные журналы. В любом случае основным механизмом стоить считать потоковют репликацию стэндбаем - она обеспечивает минимальные задержки, а может настраиваться и на синхронную работу для нулевой потери значимых транзакций

Вообще о распределении архивных журналов стоит задуматься отдельно. В Оракле мы привыкли выносить архивные журналы на отдельную ёмкость, и держать их какое то время - часы или сутки, постепенно удаляя более старые, а также выносить копии на бэкапную емкость в формате бэкапсетов RMAN или user managed backup. Также отдельная емкость резервируется на стэндбае. Вообще дублирование русурсов при резервировании данных и сервисов история правильная, и злейшим врагом тут является именно дедупликация. Бэкапы должны обеспечивать избыточность. Опыт ясно показывает, что такая избыточность часто бывает востребована на критически важных системах

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

Мониторинг состояния физического стэндбая

Для базовых целей монироринга достаточно нескольких представлений на мастере. Это pg_replication_slots, pg_stat_replication, pg_stat_database на мастере, и очень опционально pg_stat_wal_receivers и pg_stat_database_conflicts на реплике. Важным аргументом "ЗА" потоковую репликацию является факт того, что только она отображается корректно в мониторинговых представлениях. Для случая организации стэндбая с внешним копированием на него архивных журналов мониторинговые запросы нужно прорабатывать отдельно, хотя это возможно тоже. Например статусов потоковой репликации:

-- на мастере, общее состояние репликационных слотов
select * from pg_replication_slots ;

-- на мастере, общее состояние репликаций
-- сырое
select * from pg_stat_replication ;
-- все лаги по байтам - транспортный, записи, сброса и проигрывания
select pid, usesysid, state, pg_current_wal_lsn() - sent_lsn as lag_transport_bytes, sent_lsn - write_lsn as lag_write_bytes,
       wirte_lsn - flush_lsn as lag_flush_bytes, flush_lsn - replay_lsn as lag_replay_bytes
       from pg_stat_replication ;

-- более детальная информация, все лаги по байтам и времени, и общая информация по каждой репликации
select pid, usesysid, state, pg_current_wal_lsn() - sent_lsn as lag_transport_bytes, sent_lsn - write_lsn as lag_write_bytes, write_lag,
       wirte_lsn - flush_lsn as lag_flush_bytes, flush_lag, flush_lsn - replay_lsn as lag_replay_bytes, replay_lag, usename, application_name,
       client_addr, client_hostname, backend_start, backend_xmin
       from pg_stat_replication ;

-- на стэндбае
select * from pg_stat_wal_receiver ;
select * from pg_stat_database_conflicts ;

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

Белонин С.С. (С), февраль 2024 года

(даты последующих модификаций не фиксируются)


 
        
   
    Нравится     

(C) Белонин С.С., 2000-2026. Дата последней модификации страницы:2026-09-15 20:57:52