Представь, что твоя основная база данных PostgreSQL внезапно падает в самый неподходящий момент. Все приложения встают, пользователи недовольны, бизнес теряет деньги. Знакомая ситуация? Решение — грамотно настроенная репликация. Давай разберем, как настроить репликацию в PostgreSQL от А до Я, чтобы обеспечить отказоустойчивость и распределить нагрузку.
Что такое репликация в PostgreSQL и зачем она нужна
Репликация — это процесс копирования данных с одного сервера базы данных (мастера) на один или несколько других серверов (реплик). В PostgreSQL существует два основных типа:
Физическая репликация (Streaming Replication)
- Копирует базу данных на уровне файлов (WAL — Write-Ahead Log)
- Реплика — точная бинарная копия мастера
- Поддерживает только чтение на репликах (read-only)
- Идеально для высокой доступности и аварийного восстановления
Логическая репликация
- Копирует данные на уровне логических изменений (INSERT, UPDATE, DELETE)
- Позволяет реплицировать отдельные таблицы
- Реплики могут принимать запись (read-write)
- Подходит для шардинга, агрегации данных и миграций
| Критерий | Физическая репликация | Логическая репликация |
|---|---|---|
| Уровень репликации | Блоки WAL | Логические изменения |
| Гранулярность | Вся база данных | Отдельные таблицы |
| Запись на реплике | Только чтение | Чтение и запись |
| Использование | High Availability | Шардинг, агрегация |
Настройка физической репликации PostgreSQL: пошаговое руководство
Шаг 1: Подготовка мастера
На основном сервере нужно создать пользователя для репликации и настроить конфигурационные файлы.
-- Создаем пользователя для репликации
CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'StrongPassword123!';
-- Проверяем создание
\du replicator
Редактируем postgresql.conf на мастере:
# Включаем репликацию
wal_level = replica
# Минимальное количество WAL сегментов для репликации
max_wal_senders = 10
wal_keep_size = 1GB
# Разрешаем подключения
listen_addresses = '*'
# Максимальное количество одновременных подключений
max_connections = 100
Настраиваем pg_hba.conf для разрешения подключений реплики:
# Разрешаем подключение репликатора с IP реплики
host replication replicator 192.168.1.100/32 md5
# Или для всех IP в сети
host replication replicator 192.168.1.0/24 md5
sudo systemctl reload postgresql или pg_ctl reload
Шаг 2: Создание базовой копии на реплике
Останови PostgreSQL на сервере-реплике и создай резервную копию с мастера:
# Останавливаем PostgreSQL на реплике
sudo systemctl stop postgresql
# Удаляем старые данные (если есть)
sudo rm -rf /var/lib/postgresql/14/main/*
# Создаем базовую копию с мастера
pg_basebackup -h 192.168.1.50 -D /var/lib/postgresql/14/main \
-U replicator -P -v -R -W -S replica_slot1
Шаг 3: Настройка реплики
После создания базовой копии, файл standby.signal будет создан автоматически с флагом -R. Проверь наличие файла postgresql.auto.conf:
# Автоматически сгенерированный конфиг
primary_conninfo = 'host=192.168.1.50 port=5432 user=replicator password=StrongPassword123!'
primary_slot_name = 'replica_slot1'
Для горячего резервирования добавь в postgresql.conf реплики:
hot_standby = on
max_standby_streaming_delay = 30s
wal_receiver_status_interval = 10s
hot_standby_feedback = on
Шаг 4: Запуск и проверка
# Запускаем PostgreSQL на реплике
sudo systemctl start postgresql
# Проверяем статус репликации на мастере
psql -c "SELECT * FROM pg_stat_replication;"
# На реплике проверяем статус
psql -c "SELECT pg_is_in_recovery();" -- Должно вернуть 't' (true)
psql -c "\x\nSELECT * FROM pg_stat_wal_receiver;"
Настройка логической репликации PostgreSQL
Логическая репликация позволяет реплицировать отдельные таблицы, что дает больше гибкости. Давай настроим её.
Шаг 1: Подготовка мастера для логической репликации
# В postgresql.conf мастера
wal_level = logical
max_wal_senders = 10
max_replication_slots = 10
max_worker_processes = 10
-- Создаем публикацию для таблицы users
CREATE PUBLICATION users_pub FOR TABLE users;
-- Или для нескольких таблиц
CREATE PUBLICATION app_pub FOR TABLE users, orders, products;
-- Проверяем публикации
SELECT * FROM pg_publication;
Шаг 2: Настройка подписки на реплике
-- Создаем такую же таблицу на реплике
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- Создаем подписку
CREATE SUBSCRIPTION users_sub
CONNECTION 'host=192.168.1.50 port=5432 dbname=mydb user=replicator password=StrongPassword123!'
PUBLICATION users_pub;
-- Проверяем статус подписки
SELECT * FROM pg_subscription;
Шаг 3: Мониторинг логической репликации
-- На мастере: проверяем слоты репликации
SELECT * FROM pg_replication_slots;
-- На реплике: проверяем статус применения
SELECT * FROM pg_stat_subscription;
-- Проверяем задержку репликации
SELECT
application_name,
write_lag,
flush_lag,
replay_lag
FROM pg_stat_replication;
Мониторинг и управление репликацией
Полезные команды для мониторинга
-- Основные представления для мониторинга
SELECT * FROM pg_stat_replication; -- Активные подключения реплик
SELECT * FROM pg_stat_wal_receiver; -- Статус получения WAL
SELECT * FROM pg_current_wal_lsn(); -- Текущая позиция WAL
SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)
FROM pg_stat_replication; -- Задержка репликации в байтах
-- Проверка слотов репликации
SELECT slot_name, active, wal_status
FROM pg_replication_slots;
Решение распространенных проблем
Решение: Увеличь
wal_keep_size, проверь сетевую связность, увеличь max_wal_senders
Решение: Проверь пароль репликатора, настройки pg_hba.conf и наличие слота репликации
# Принудительный перезапуск репликации
# На реплике:
sudo systemctl stop postgresql
sudo rm -rf /var/lib/postgresql/14/main/*
# Повторное создание базовой копии
pg_basebackup -h мастер -D /var/lib/postgresql/14/main -U replicator -P -v -R
Автоматизация и лучшие практики
- Используйте слоты репликации для предотвращения потери WAL
- Настройте мониторинг задержки репликации (prometheus + postgres_exporter)
- Регулярно проверяйте размер WAL файлов и очищайте старые слоты
- Используйте отдельные сети для трафика репликации
- Тестируйте процедуру переключения на реплику (failover) регулярно
# Пример скрипта для проверки репликации
#!/bin/bash
MASTER="192.168.1.50"
REPLICA="192.168.1.100"
# Проверяем, что реплика работает
LAG=$(psql -h $MASTER -U postgres -t -c \
"SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) FROM pg_stat_replication WHERE application_name='replica1';")
if [ "$LAG" -gt 104857600 ]; then # 100MB
echo "WARNING: Replication lag is high: $LAG bytes"
exit 1
fi
echo "OK: Replication is healthy, lag: $LAG bytes"
Часто задаваемые вопросы (FAQ)
Можно ли настроить несколько реплик с одного мастера?
Да, PostgreSQL поддерживает каскадную репликацию и multiple standby. Просто создай отдельные слоты репликации и настрой подключения для каждой реплики.
Как выполнить переключение (failover) на реплику?
На реплике выполни: pg_ctl promote или создай файл promote.signal в каталоге данных. После этого реплика станет основной и сможет принимать запись.
Можно ли настроить репликацию между разными версиями PostgreSQL?
Физическая репликация обычно требует одинаковых мажорных версий. Логическая репликация более гибкая, но проверяйте совместимость в документации для конкретных версий.
Как реплицировать только часть таблицы?
Для логической репликации можно использовать условия в публикации (WHERE clause) начиная с PostgreSQL 15. Для более старых версий — создавайте представления и реплицируйте их.
Заключение
Настройка репликации в PostgreSQL — критически важный навык для любого DevOps-инженера. Физическая репликация обеспечивает высокую доступность и быстрое восстановление после сбоев, а логическая репликация открывает возможности для сложных архитектурных решений.
Ключевые моменты для успешной настройки:
- Всегда тестируй настройку в staging-окружении перед продакшеном
- Настрой мониторинг задержки репликации
- Документируй процедуру failover
- Регулярно проверяй работоспособность репликации
Помни: правильно настроенная репликация — это не просто бэкап, это стратегический компонент отказоустойчивой архитектуры.