Пошаговое руководство по настройке физической (streaming) и логической репликации PostgreSQL с конкретными командами, параметрами и сценариями переключения мастера. Подходит для версий PostgreSQL 12–16, актуально на 2025–2026 годы.
Статья была полезной?
Репликация PostgreSQL обеспечивает отказоустойчивость и масштабирование чтения при сохранении согласованности данных. Ниже — практическая инструкция по настройке streaming (физической) и logical (логической) репликации с примерами команд и конкретными значениями параметров.
PostgreSQL поддерживает два основных типа репликации: физическую (streaming/файловая) и логическую (logical). Физическая репликация копирует бинарные WAL записи и используется для горячих standby и быстрых failover; логическая репликация пересылает DML в виде репликатов (INSERT/UPDATE/DELETE) и годится для репликации данных между разными версиями или частичной синхронизации таблиц.
wals_level = replica или выше.hot_standby = on, часто используется вместе с streaming.wals_level = logical и дополнительных слотов репликации.Практика: для OLTP-системы с нагрузкой 10 000 rps обычно ставят max_wal_senders = 5, max_replication_slots = 5, max_wal_size = 4GB, wal_keep_size = 1GB.

Схема streaming replication PostgreSQL
Цель шага — настроить физическую репликацию master -> standby с использованием pg_basebackup и streaming WAL. Примеры актуальны для PostgreSQL 12–16 (2025–2026). В примере мастер: 10.0.0.10, реплика: 10.0.0.11, пользователь репликации: replicator.
listen_addresses = '*'
wal_level = logical
max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 1024MB
max_wal_size = 4GB
checkpoint_timeout = 5min
archive_mode = on
archive_command = 'test ! -f /var/lib/pgsql/wal_archive/%f && cp %p /var/lib/pgsql/wal_archive/%f' Здесь wal_level = logical подходит и для физической репликации; если нужен только физический — можно установить replica, но для гибридных сценариев устанавливайте logical.host replication replicator 10.0.0.11/32 md5 Стоимость: создайте пароль пользователя replicator с сильной строкой не менее 16 символов.sudo systemctl reload postgresql-14 или sudo pg_ctlcluster 14 main reload на Debian/Ubuntu.psql -U postgres -c "CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'S0m3$tr0ngP@ssw0rd'"Проверьте, что пользователь увидит только репликацию, без лишних привилегий.
На реплике выполните:
sudo systemctl stop postgresql-14
sudo -u postgres rm -rf /var/lib/pgsql/14/data/*
sudo -u postgres pg_basebackup -h 10.0.0.10 -D /var/lib/pgsql/14/data -U replicator -P -X stream --wal-method=streamПример времени: для БД 200GB по сети 1Gbps команда занимает ~30–40 минут (фактически зависит от дисков и сети). Параметр -X stream захватывает WAL во время basebackup.
Для PostgreSQL 12+ создайте файл /var/lib/pgsql/14/data/standby.signal и конфиг postgresql.auto.conf или recovery.conf (в новых версиях recovery параметры прописываются в postgresql.conf или recovery.signal). Пример минимальной конфигурации в postgresql.auto.conf:
primary_conninfo = 'host=10.0.0.10 port=5432 user=replicator password=S0m3$tr0ngP@ssw0rd application_name=standby1'
primary_slot_name = 'standby1_slot'
hot_standby = onЕсли используете слоты репликации, создайте слот на мастере: SELECT * FROM pg_create_physical_replication_slot('standby1_slot');
На мастере проверьте статус слотов и senders:
SELECT slot_name, plugin, slot_type, active FROM pg_replication_slots;
SELECT pid, state, application_name, client_addr FROM pg_stat_replication;На реплике убедитесь, что процессы WAL receiver запущены и pg_is_in_recovery() возвращает true.

Схема logical replication PostgreSQL
Hot standby позволяет выполнять только чтение на реплике во время репликации. Настройка заточена под низкое время отклика для read-only нагрузок.
hot_standby = on — обязателен.synchronous_commit выбирайте исходя из RPO: synchronous_commit = on для минимального риска потери данных, remote_write для меньшей задержки.synchronous_standby_names = '1 (standby1)' — при синхронной репликации гарантирует подтверждение записи на заданной реплике.Создайте роль read-only для приложения аналитики и ограничьте соединения к реплике по pg_hba.conf, например:
CREATE ROLE analytics LOGIN PASSWORD 'Analyt1cs$' NOSUPERUSER;
GRANT CONNECT ON DATABASE mydb TO analytics;
GRANT USAGE ON SCHEMA public TO analytics;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO analytics;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO analytics;При нагрузке чтения 1000 QPS распределяйте трафик через PgBouncer или репликационный прокси, чтобы не перегружать реплику.
Используйте следующие запросы для контроля задержки (lag):
SELECT application_name, client_addr, state,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS byte_lag
FROM pg_stat_replication;
-- На реплике
SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay;Целевой показатель: replication_delay < 500 ms для большинства OLTP-систем. Если > 2 s — проверьте сеть и дисковую производительность.
max_wal_size=8GB и checkpoint_timeout=10min.Логическая репликация полезна для репликации поднаборов таблиц, миграции между мажорными версиями и многомастеров. В примере развернем публикацию на master и подпишем реплику.
В postgresql.conf поставьте:
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10Перезапустите сервер: sudo systemctl restart postgresql-15. Пример даты: изменение применено 2026-02-10 на продуктиве.
-- На master
psql -U postgres -d mydb -c "CREATE PUBLICATION pub_all FOR ALL TABLES;"
-- или частичный набор
psql -U postgres -d mydb -c "CREATE PUBLICATION pub_orders FOR TABLE orders, order_items;"Публикация отправляет DML в формат формата pgoutput по умолчанию.
На реплике выполните:
-- На standby, но не в режиме hot standby как физическая репликация; обычно логическая репликация ставится на отдельный узел
psql -U postgres -d mydb -c "CREATE SUBSCRIPTION sub1 CONNECTION 'host=10.0.0.10 port=5432 user=replicator password=S0m3$tr0ngP@ssw0rd dbname=mydb' PUBLICATION pub_all;
"При создании подписки происходит начальная синхронизация данных (COPY). Для больших таблиц можно использовать copy_data = false и заполнить данные бэкапом.
Логические слоты удерживают WAL до тех пор, пока подписка не подтянет данные; мониторьте возраст слотов:
SELECT slot_name, plugin, active, pg_size_pretty(pg_xlog_location_diff(pg_current_wal_lsn(), restart_lsn)) as retained
FROM pg_replication_slots WHERE slot_type='logical';Если слот стареет и удерживает много WAL (>10GB), планируйте увеличение хранения или удаление неиспользуемых подписок.
Ссылка на похожий материал по работе с PostgreSQL: Статьи по PostgreSQL.
Приведены пошаговые инструкции для ручного failover и автоматизированного переключения с использованием repmgr. Пример подтвержден на стенде 2025-11-12.
SELECT application_name, client_addr, state, sync_state FROM pg_stat_replication;
-- выберите наиболее актуальную реплику с минимальным lagsudo -u postgres pg_ctl -D /var/lib/pgsql/14/data promote
-- или
sudo systemctl start postgresql-14 && sudo -u postgres touch /var/lib/pgsql/14/data/trigger_file && sudo systemctl reload postgresql-14 Команда работает быстро: promote обычно занимает 1–3 секунды плюс replay WAL.Распределение: реплика 1 — priority 100, реплика 2 — 90. Установка repmgr 5.x (совместима с PostgreSQL 12–15):
-- На каждом узле /etc/repmgr/14/repmgr.conf
cluster=repl_cluster
node_id=2
node_name='standby1'
host='10.0.0.11'
conninfo='host=10.0.0.11 user=repmgr dbname=repmgr'
priority=100
promote_command='repmgr standby promote'
follow_command='repmgr standby follow --log-level-console INFO'repmgr выполняет мониторинг и сможет автоматически продвигать реплику при падении мастера. В продакшне тестируйте failover на отдельном окружении не реже одного раза в квартал.
pg_rewind дальше.Для примера автоматизации переключения используйте скрипт, который выполняет promote, проверяет WAL replay и обновляет VIP. Скрипт должен иметь тайм-ауты: максимум 5 минут на полный переход.
Полезный материал по администрированию: Руководства по Linux.
Split brain возникает, когда два узла принимают записи одновременно. Это критическая ситуация; решение включает анализ divergence, выбор новой единой ветки и синхронизацию остального кластера.
SELECT pg_current_wal_lsn(), pg_walfile_name(pg_current_wal_lsn()) AS current_walfile, pg_is_in_recovery();
SELECT timeline_id FROM pg_control_checkpoint(); -- или просмотр истории timelineСделайте выбор на основе критериев: наиболее свежие критически важные транзакции, минимальная потеря данных, SLA. Документируйте дату и время выбора (например: 2026-01-18T14:23:00Z) для последующего аудита.
Если выбран основной мастер A, и мастер B ранее писал, безопаснее остановить B, сделать pg_rewind по отношению к A и затем подключить B как реплику. Команды:
# На A (новый мастер) должен быть доступен
-- убедитесь, что на A включено логирование и есть подключение
# На B остановите PostgreSQL
sudo systemctl stop postgresql-14
# На B очистите конфиг, сохраните postgresql.conf
sudo -u postgres pg_rewind --target-pgdata=/var/lib/pgsql/14/data --source-server='host=10.0.0.10 user=repl_user port=5432' --progress
# После завершения запустите B как реплику
sudo -u postgres touch /var/lib/pgsql/14/data/standby.signal
# добавьте primary_conninfo в postgresql.auto.conf
sudo systemctl start postgresql-14pg_rewind копирует только отличия и работает быстро: для 200GB порядка 10–20 минут при высокопроизводительных дисках. Если данные сильно расходятся, может потребоваться полная пересборка через pg_basebackup.
Рекомендации:
Всегда тестируйте сценарии failover и pg_rewind на стенде не реже одного раза в квартал. Документируйте действия и храните скрипты переключения в версии контроля.
Выбор зависит от задачи: если нужно точное поблочное копирование и быстрый failover — streaming (физическая репликация). Если требуется реплицировать только часть таблиц, миграция между версиями PostgreSQL или репликация между разными схемами — logical. Logical требует wals_level = logical и использует репликационные слоты, которые удерживают WAL. Для гибридных конфигураций часто ставят wals_level = logical и настраивают и физические, и логические механизмы одновременно.
Минимум 2 реплики рекомендуется для обеспечения отказоустойчивости: одна синхронная (synchronous_standby_names = '1 (replica1)') и одна асинхронная для географического распределения. Для SLA 99.95% обычно используют 2–3 реплики в разных AZ/дата-центрах. Если нужен компактный RPO < 1 с, ставьте как минимум одну синхронную реплику и используйте быстрые сети 10Gbps и SSD NVMe.
Replication slots предотвращают удаление WAL, пока реплика не прочитала данные. Физические слоты — для streaming, логические — для logical replication. Мониторьте их размер запросом к pg_replication_slots и ограничивайте количество слотов (например, max_replication_slots = 10). Если слот неактивен более 24 часов и удерживает WAL > 10GB, планируйте принудительное удаление после анализа: SELECT pg_drop_replication_slot('slotname');. Для логических подписок контролируйте долгие initial copy и при необходимости используйте copy_data = false.
pg_rewind синхронизирует старый мастер (который еще содержит write-паттерны, несовместимые с новым мастером) с текущим мастером без полного резервного копирования. Используется после failover, когда старый мастер может быть «отставшим» и требует отката к точке, где начался новый мастер. pg_rewind эффективен для крупных баз: сокращает время восстановления с часов до десятков минут, если divergence небольшое. Перед применением убедитесь, что new master сохраняет историю WAL, доступную для rewind.
Планируйте WAL-архивирование исходя из транзакционной активности. Для среднего OLTP с 100 GB данных в день можно рассчитывать на 1–4 GB WAL в час; для высокой нагрузки — 10–20 GB/час. Настройте max_wal_size (например, 4–8GB) и wal_keep_size (например, 1024MB–4096MB) и храните архивы на отдельном диске или S3 с ретеншеном 7–30 дней. Проверяйте использование диска по cron и alert'ам при достижении 70% заполнения.
Комментарии (0)
Войдите или зарегистрируйтесь, чтобы оставить комментарий
Загрузка комментариев…