Пошаговое руководство по настройке физической (streaming) и логической репликации PostgreSQL с конкретными командами, параметрами и сценариями переключения мастера. Подходит для версий PostgreSQL 12–16, актуально на 2025–2026 годы.
0
Статья была полезной?
Комментарии (0)
Войдите или зарегистрируйтесь, чтобы оставить комментарий
Загрузка комментариев…
Репликация PostgreSQL обеспечивает отказоустойчивость и масштабирование чтения при сохранении согласованности данных. Ниже — практическая инструкция по настройке streaming (физической) и logical (логической) репликации с примерами команд и конкретными значениями параметров.
Типы репликации PG
PostgreSQL поддерживает два основных типа репликации: физическую (streaming/файловая) и логическую (logical). Физическая репликация копирует бинарные WAL записи и используется для горячих standby и быстрых failover; логическая репликация пересылает DML в виде репликатов (INSERT/UPDATE/DELETE) и годится для репликации данных между разными версиями или частичной синхронизации таблиц.
Физическая (streaming) — репликация на уровне блоков/WAL, требует одинаковых major-версий PostgreSQL, минимальные параметры: wals_level = replica или выше.
Горячий standby (hot standby) — режим чтения на реплике, требует hot_standby = on, часто используется вместе с streaming.
Логическая (logical) — для публикации/подписки таблиц: требует 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
Шаг 1: streaming replication
Цель шага — настроить физическую репликацию master -> standby с использованием pg_basebackup и streaming WAL. Примеры актуальны для PostgreSQL 12–16 (2025–2026). В примере мастер: 10.0.0.10, реплика: 10.0.0.11, пользователь репликации: replicator.
1.1. Подготовка master
В postgresql.conf (обычно /var/lib/pgsql/14/data/postgresql.conf) задайте параметры:
Здесь wal_level = logical подходит и для физической репликации; если нужен только физический — можно установить replica, но для гибридных сценариев устанавливайте logical.
В pg_hba.conf добавьте строку для репликации:
host replication replicator 10.0.0.11/32 md5
Стоимость: создайте пароль пользователя replicator с сильной строкой не менее 16 символов.
Перезапустите сервер:
sudo systemctl reload postgresql-14
или sudo pg_ctlcluster 14 main reload на Debian/Ubuntu.
1.2. Создание пользователя репликации
psql -U postgres -c "CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'S0m3$tr0ngP@ssw0rd'"
Проверьте, что пользователь увидит только репликацию, без лишних привилегий.
1.3. Создание физической реплики через pg_basebackup
Пример времени: для БД 200GB по сети 1Gbps команда занимает ~30–40 минут (фактически зависит от дисков и сети). Параметр -X stream захватывает WAL во время basebackup.
1.4. Подключение реплики
Для PostgreSQL 12+ создайте файл /var/lib/pgsql/14/data/standby.signal и конфиг postgresql.auto.conf или recovery.conf (в новых версиях recovery параметры прописываются в postgresql.conf или recovery.signal). Пример минимальной конфигурации в postgresql.auto.conf:
Если используете слоты репликации, создайте слот на мастере: SELECT * FROM pg_create_physical_replication_slot('standby1_slot');
1.5. Проверка состояния
На мастере проверьте статус слотов и 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
Шаг 2: hot standby
Hot standby позволяет выполнять только чтение на реплике во время репликации. Настройка заточена под низкое время отклика для read-only нагрузок.
2.1. Параметры для низкой латентности чтения
hot_standby = on — обязателен.
synchronous_commit выбирайте исходя из RPO: synchronous_commit = on для минимального риска потери данных, remote_write для меньшей задержки.
synchronous_standby_names = '1 (standby1)' — при синхронной репликации гарантирует подтверждение записи на заданной реплике.
2.2. Настройка read-only пользователей
Создайте роль 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 или репликационный прокси, чтобы не перегружать реплику.
2.3. Мониторинг задержки репликации
Используйте следующие запросы для контроля задержки (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 — проверьте сеть и дисковую производительность.
Практическая рекомендация: для SSD и 10k IOPS установите max_wal_size=8GB и checkpoint_timeout=10min.
Шаг 3: logical replication
Логическая репликация полезна для репликации поднаборов таблиц, миграции между мажорными версиями и многомастеров. В примере развернем публикацию на master и подпишем реплику.
Перезапустите сервер: sudo systemctl restart postgresql-15. Пример даты: изменение применено 2026-02-10 на продуктиве.
3.2. Создание публикации
-- На 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 по умолчанию.
3.3. Создание подписки на реплике
На реплике выполните:
-- На 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 и заполнить данные бэкапом.
3.4. Управление слотами и очистка
Логические слоты удерживают 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), планируйте увеличение хранения или удаление неиспользуемых подписок.
3.5. Сценарии использования logical
Миграция данных между версиями PostgreSQL с минимальным downtime — создаете публикацию на старом мастере, подписку на новом и переключаете приложения после catch-up.
Реализация многимастера для отдельных таблиц (например, географическое распределение) — держите разные публикации на разных мастерах.
Приведены пошаговые инструкции для ручного failover и автоматизированного переключения с использованием repmgr. Пример подтвержден на стенде 2025-11-12.
4.1. Ручной failover (примордиальный сценарий)
Проверка состояния реплик:
SELECT application_name, client_addr, state, sync_state FROM pg_stat_replication;
-- выберите наиболее актуальную реплику с минимальным lag
Остановите запись на старом мастере (если он доступен): остановите приложение или заблокируйте запись через прокси. Это важно, чтобы не допустить split-brain.
repmgr выполняет мониторинг и сможет автоматически продвигать реплику при падении мастера. В продакшне тестируйте failover на отдельном окружении не реже одного раза в квартал.
4.3. Проверка после переключения
Проверьте, что старый мастер остановлен или переведен в standby (если планируете его вернуть как реплику): используйте pg_rewind дальше.
На новом мастере создайте необходимые слоты и публикации: для физических реплик создайте физслот или рекомбинируйте через pg_basebackup.
Обновите мониторинг и оповещения (Prometheus, Zabbix) на новый адрес.
Для примера автоматизации переключения используйте скрипт, который выполняет promote, проверяет WAL replay и обновляет VIP. Скрипт должен иметь тайм-ауты: максимум 5 минут на полный переход.
Split brain возникает, когда два узла принимают записи одновременно. Это критическая ситуация; решение включает анализ divergence, выбор новой единой ветки и синхронизацию остального кластера.
5.1. Быстрая диагностика
Обнаружьте наличие двух мастеров: проверьте, какие узлы принимают записи, через monitoring и приложение. Логи Postgres покажут подтверждения записи и различия timeline.
На каждом мастере выполните:
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
Определите, какие данные уникальны для каждой ветки: выполните контрольные суммы таблиц или SELECT COUNT и сравните по ключевым таблицам.
5.2. Выбор основной ветки
Сделайте выбор на основе критериев: наиболее свежие критически важные транзакции, минимальная потеря данных, SLA. Документируйте дату и время выбора (например: 2026-01-18T14:23:00Z) для последующего аудита.
5.3. Использование pg_rewind для синхронизации старого мастера
Если выбран основной мастер 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-14
pg_rewind копирует только отличия и работает быстро: для 200GB порядка 10–20 минут при высокопроизводительных дисках. Если данные сильно расходятся, может потребоваться полная пересборка через pg_basebackup.
5.4. Что делать при сильном расхождении
Если таблицы имеют конфликтующие записи (например, один мастер записал запись с PK=100, другой — тоже PK=100 с разными данными), придется вручную разрешать конфликт: восстановить из бэкапа, применить ETL/merge script, или откатить часть транзакций.
Для больших наборов данных используйте экспорт/импорт (COPY) или специализированные инструменты сравнения схем и данных (pg_dump/pg_restore, oxc). Планируйте окно работ минимум 2–6 часов для средних баз 500GB.
5.5. Предотвращение split brain
Рекомендации:
Используйте кворумное управление VIP/DNS (keepalived с check script), чтобы точно знать, где находится мастер.
Настройте мониторинг задержки и alert'ы: оповещение при replication_delay > 2s и при потере связи с master более 30 s.
Всегда тестируйте сценарии failover и pg_rewind на стенде не реже одного раза в квартал. Документируйте действия и храните скрипты переключения в версии контроля.
Частые вопросы
как правильно выбрать между logical и streaming?
Выбор зависит от задачи: если нужно точное поблочное копирование и быстрый failover — streaming (физическая репликация). Если требуется реплицировать только часть таблиц, миграция между версиями PostgreSQL или репликация между разными схемами — logical. Logical требует wals_level = logical и использует репликационные слоты, которые удерживают WAL. Для гибридных конфигураций часто ставят wals_level = logical и настраивают и физические, и логические механизмы одновременно.
сколько реплик ставить для HA?
Минимум 2 реплики рекомендуется для обеспечения отказоустойчивости: одна синхронная (synchronous_standby_names = '1 (replica1)') и одна асинхронная для географического распределения. Для SLA 99.95% обычно используют 2–3 реплики в разных AZ/дата-центрах. Если нужен компактный RPO < 1 с, ставьте как минимум одну синхронную реплику и используйте быстрые сети 10Gbps и SSD NVMe.
зачем нужны replication slots и как контролировать их размер?
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 и когда его использовать?
pg_rewind синхронизирует старый мастер (который еще содержит write-паттерны, несовместимые с новым мастером) с текущим мастером без полного резервного копирования. Используется после failover, когда старый мастер может быть «отставшим» и требует отката к точке, где начался новый мастер. pg_rewind эффективен для крупных баз: сокращает время восстановления с часов до десятков минут, если divergence небольшое. Перед применением убедитесь, что new master сохраняет историю WAL, доступную для rewind.
сколько места нужно для WAL и как резервировать?
Планируйте 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)
Войдите или зарегистрируйтесь, чтобы оставить комментарий
Загрузка комментариев…