PostgreSQL 17 репликация: настройка master-slave, streaming, логическая | AdminWiki

Настройка репликации в PostgreSQL 17: пошаговое руководство для DevOps

18 декабря 2025 8 мин. чтения #PostgreSQL 17 #devops #high availability #postgresql #базы данных #настройка #репликация
Содержание статьи

Введение: Зачем нужна репликация PostgreSQL 17?

Представь, что твоя база данных — это сердце приложения. Остановилось сердце — умерло приложение. Репликация в PostgreSQL 17 создает точные копии (реплики) твоей базы, обеспечивая отказоустойчивость, балансировку нагрузки и возможность горячего резервирования. Давай разберем, как правильно настроить этот механизм.

В PostgreSQL 17 разработчики улучшили как физическую (streaming replication), так и логическую репликацию, добавив новые возможности мониторинга и управления.

Типы репликации в PostgreSQL 17: что выбрать?

Перед настройкой нужно понять, какой тип репликации подходит твоим задачам. Вот основные варианты:

Тип Как работает Плюсы Минусы Когда использовать
Физическая (Streaming) Копирует бинарные WAL-файлы с мастера на реплику
  • Полная консистентность
  • Высокая производительность
  • Простая настройка
  • Реплика только для чтения
  • Вся БД целиком
High Availability, резервные копии
Логическая Передает логические изменения (INSERT/UPDATE/DELETE)
  • Выборочная репликация таблиц
  • Реплика для записи
  • Разные версии PostgreSQL
  • Больше накладных расходов
  • Сложнее настройка
Шардинг, апгрейд версий, отчеты
Синхронная Транзакция фиксируется только после подтверждения от реплики
  • Гарантия нулевой потери данных
  • Strong consistency
  • Задержки записи
  • Риск недоступности
Финансовые системы
Совет ментора: Для большинства проектов начинай с асинхронной потоковой репликации. Она дает хороший баланс между надежностью и производительностью.

Пошаговая настройка потоковой репликации PostgreSQL 17

Давай настроим классическую master-slave архитектуру. Представь, что у тебя два сервера: master-pg (192.168.1.10) и replica-pg (192.168.1.20).

Шаг 1: Подготовка мастера (Primary)

Сначала создадим пользователя для репликации и настроим конфигурацию:

bash
# На мастере создаем пользователя для репликации
sudo -u postgres psql
CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'StrongPassword123!';
\du replicator  # Проверяем создание

Теперь редактируем основные конфигурационные файлы:

config
# /etc/postgresql/17/main/postgresql.conf
# Включаем сетевой доступ
listen_addresses = '*'  # Или конкретный IP

# Настройки репликации
wal_level = replica             # Минимум для потоковой репликации
max_wal_senders = 10            # Максимум подключений реплик
wal_keep_size = 1024            # Минимум 1GB WAL файлов для реплик
hot_standby = on                # Для чтения на реплике

# В PostgreSQL 17 появилась улучшенная настройка:
# wal_receiver_create_temp_slot = on  # Автосоздание временных слотов
config
# /etc/postgresql/17/main/pg_hba.conf
# Добавляем правило для репликации
# TYPE  DATABASE  USER       ADDRESS        METHOD
host    replication  replicator  192.168.1.20/32  scram-sha-256
# Или для всей сети реплик:
host    replication  replicator  192.168.1.0/24   scram-sha-256
Внимание: Не используй trust метод в продакшене! Всегда используй scram-sha-256 или сертификаты.

Шаг 2: Создание базовой резервной копии

На реплике нам нужна стартовая копия данных. Используем pg_basebackup:

bash
# На реплике останавливаем PostgreSQL, если запущен
sudo systemctl stop postgresql

# Удаляем старые данные (если есть)
sudo -u postgres rm -rf /var/lib/postgresql/17/main/*

# Забираем бэкап с мастера
sudo -u postgres pg_basebackup \
  -h 192.168.1.10 \
  -p 5432 \
  -U replicator \
  -D /var/lib/postgresql/17/main \
  -Fp \           # plain format (файлы)
  -Xs \           # stream WAL во время копирования
  -R \            # автоматически создаст standby.signal и конфиг
  -P               # прогресс-бар

# Введи пароль replicator когда запросит

Шаг 3: Настройка реплики (Standby)

После pg_basebackup -R файл postgresql.auto.conf уже создан. Проверим его:

config
# /var/lib/postgresql/17/main/postgresql.auto.conf
primary_conninfo = 'host=192.168.1.10 port=5432 user=replicator password=StrongPassword123!'
primary_slot_name = 'pg_basebackup_1'  # Или свое имя

Дополнительно создадим файл standby.signal (если не создан):

bash
sudo -u postgres touch /var/lib/postgresql/17/main/standby.signal

Шаг 4: Запуск и проверка

bash
# Запускаем PostgreSQL на реплике
sudo systemctl start postgresql

# Смотрим логи на реплике
sudo tail -f /var/log/postgresql/postgresql-17-main.log
# Должны увидеть:
# "database system is ready to accept read-only connections"
# "started streaming WAL from primary"

Проверяем статус репликации на мастере:

sql
-- На мастере
SELECT * FROM pg_stat_replication;

-- Должны увидеть:
-- application_name | client_addr  | state      | sync_state | write_lag
-- -----------------+--------------+------------+------------+-----------
-- walreceiver      | 192.168.1.20 | streaming  | async      | 00:00:00.123456

Настройка логической репликации в PostgreSQL 17

Логическая репликация позволяет выбирать конкретные таблицы. Допустим, нам нужно реплицировать только таблицы users и orders.

Шаг 1: Настройка публикации на мастере

sql
-- В postgresql.conf мастера
wal_level = logical  # Важно: logical вместо replica

-- Создаем публикацию
CREATE PUBLICATION my_publication FOR TABLE users, orders;

-- Или все таблицы:
CREATE PUBLICATION all_tables FOR ALL TABLES;

-- Проверяем
\dRp+

Шаг 2: Настройка подписки на реплике

sql
-- На реплике создаем таблицы (структуру)
-- Они должны существовать перед созданием подписки

-- Создаем подписку
CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=192.168.1.10 port=5432 dbname=mydb user=replicator password=StrongPassword123!'
PUBLICATION my_publication
WITH (copy_data = true);  -- Копировать существующие данные

-- Проверяем статус
SELECT * FROM pg_stat_subscription;
Новое в PostgreSQL 17: Улучшена производительность логической репликации, особенно для транзакций с большим количеством изменений. Добавлены новые столбцы в pg_stat_subscription для мониторинга.

Мониторинг и управление репликацией

sql
-- Основные команды мониторинга

-- 1. Статус потоковой репликации
SELECT
  application_name,
  client_addr,
  state,
  sync_state,
  write_lag,
  flush_lag,
  replay_lag,
  sent_lsn,
  write_lsn,
  flush_lsn,
  replay_lsn
FROM pg_stat_replication;

-- 2. Проверка лагов репликации
SELECT
  pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag_bytes,
  pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) AS replay_lag_pretty
FROM pg_stat_replication;

-- 3. Для логической репликации
SELECT * FROM pg_stat_subscription;
SELECT * FROM pg_replication_slots;  # Слоты репликации

-- 4. Принудительная промоушн реплики в мастера (failover)
-- На реплике:
SELECT pg_promote();
-- Или: touch /tmp/promote_me

Типичные проблемы и решения

Проблема 1: Реплика отстает (replication lag)

Симптомы: Большие значения write_lag, реплика не успевает за мастером.

Решение:

  • Увеличить wal_keep_size на мастере
  • Проверить сетевую задержку между серверами
  • На реплике увеличить max_standby_streaming_delay
  • Оптимизировать запросы на реплике (если она для чтения)

Проблема 2: Репликация не запускается

Проверь:

  • Файл standby.signal существует на реплике
  • Правила в pg_hba.conf на мастере
  • Пароль в primary_conninfo правильный
  • Сетевой доступ между серверами (firewall)
  • Логи PostgreSQL на обоих серверах

Автоматизация и DevOps лучшие практики

bash
#!/bin/bash
# Пример скрипта для мониторинга репликации
# Сохрани как check_replication.sh

PRIMARY_HOST="192.168.1.10"
REPLICA_HOST="192.168.1.20"
THRESHOLD_KB=1048576  # 1GB в килобайтах

# Проверяем лаг репликации
LAG_KB=$(psql -h $PRIMARY_HOST -U postgres -t -c \
  "SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)/1024 \
   FROM pg_stat_replication WHERE client_addr = '$REPLICA_HOST'")

if [ -z "$LAG_KB" ]; then
  echo "ERROR: Репликация не активна!"
  exit 1
elif [ $LAG_KB -gt $THRESHOLD_KB ]; then
  echo "WARNING: Лаг репликации ${LAG_KB}KB превышает порог"
  exit 2
else
  echo "OK: Лаг репликации ${LAG_KB}KB"
  exit 0
fi
Совет DevOps: Используй инструменты вроде Patroni, repmgr или собственные скрипты для автоматического failover. Настрой алертинг на лаг репликации в мониторинге (Prometheus + Grafana).

Часто задаваемые вопросы (FAQ)

Можно ли настроить несколько реплик с одного мастера?

Да, PostgreSQL поддерживает множество реплик. Просто настрой каждую реплику как описано выше. Убедись, что max_wal_senders на мастере достаточно для всех подключений.

Как переключить реплику на запись при падении мастера?

На реплике выполни SELECT pg_promote(); или создай файл /tmp/promote_me. После этого отредактируй конфиги приложений, чтобы они указывали на новый мастер.

В чем разница между синхронной и асинхронной репликацией?

Синхронная: транзакция фиксируется только после подтверждения от реплики (гарантия данных, но задержки). Асинхронная: транзакция фиксируется сразу, реплика догоняет (лучшая производительность, риск потери данных при падении мастера).

Как добавить новую таблицу в существующую логическую репликацию?

На мастере: ALTER PUBLICATION my_publication ADD TABLE new_table;. На реплике таблица должна уже существовать, затем перезапусти подписку или подожди автоматического обновления.

Заключение

Настройка репликации в PostgreSQL 17 — критически важный навык для любого DevOps-инженера. Мы разобрали:

  • Различия между физической и логической репликацией
  • Пошаговую настройку потоковой репликации
  • Особенности логической репликации для выборочного копирования
  • Мониторинг и решение типичных проблем

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

Поделиться:
Сохранить гайд? В закладки браузера