PostgreSQL replication: streaming и логическая
PostgreSQL поддерживает два типа репликации: streaming (физическая) для high availability и disaster recovery, и логическая для CDC (Change Data Capture) и синхронизации между разными системами.
Streaming replication
Streaming replication передаёт WAL-записи (Write-Ahead Log) с primary на standby в реальном времени. Standby-сервер может быть использован для чтения и автоматического failover.
Настройка primary
# postgresql.conf на primary
wal_level = replica
max_wal_senders = 5
wal_keep_size = '1GB'
synchronous_commit = on
# pg_hba.conf
host replication replicator 10.0.0.0/24 scram-sha-256
Создание пользователя репликации
CREATE USER replicator WITH REPLICATION LOGIN PASSWORD 'secure_password';
Настройка standby
# Инициализация standby с primary
pg_basebackup -h primary_host -U replicator -D /var/lib/postgresql/data -Fp -Xs -P -R
# Файл standby.signal создаётся автоматически с -R флагом
# postgresql.conf на standby
primary_conninfo = 'host=primary_host port=5432 user=replicator password=secure_password'
hot_standby = on
Проверка статуса репликации
# На primary
SELECT client_addr, state, sent_lsn, write_lsn, replay_lsn,
replay_lag FROM pg_stat_replication;
# На standby
SELECT pg_is_in_recovery();
SELECT now() - pg_last_xact_replay_timestamp() AS replication_lag;
Синхронная vs асинхронная репликация
# Синхронная репликация (на primary)
synchronous_standby_names = 'FIRST 1 (standby1, standby2)'
# Это гарантирует, что транзакция подтверждается только после
# записи на как минимум один standby
Синхронная репликация снижает производительность записи. Используйте её только для критичных данных, где потеря даже одной транзакции недопустима.
Логическая репликация
Логическая репликация работает на уровне таблиц и позволяет реплицировать изменения в формате, понятном другим системам. Идеальна для CDC и миграций.
Настройка
# postgresql.conf (на обеих сторонах)
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
Публикация (на primary)
-- Создание публикации
CREATE PUBLICATION my_pub FOR TABLE orders, customers;
-- Или для всех таблиц
CREATE PUBLICATION my_pub FOR ALL TABLES;
Подписка (на standby)
-- Создание подписки
CREATE SUBSCRIPTION my_sub
CONNECTION 'host=primary_host dbname=mydb user=replicator password=secret'
PUBLICATION my_pub;
Replication slots
Replication slots предотвращают удаление WAL до его чтения репликой. Это критично для логической репликации и CDC:
-- Создание слота
SELECT pg_create_physical_replication_slot('standby_slot');
SELECT pg_create_logical_replication_slot('cdc_slot', 'pgoutput');
-- Просмотр слотов
SELECT slot_name, slot_type, active, restart_lsn FROM pg_replication_slots;
-- Удаление неактивных слотов
SELECT pg_drop_replication_slot('old_slot');
CDC с логической репликацией
-- Настройка publications для CDC
ALTER PUBLICATION my_pub SET (publish = 'insert, update, delete');
-- Просмотр изменений через pgoutput
-- (используется в conjunction с Debezium, Kafka Connect и др.)
-- Пример интеграции с Debezium:
-- connector.json
{
"name": "postgres-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "primary_host",
"database.port": "5432",
"database.user": "replicator",
"database.password": "secret",
"database.dbname": "mydb",
"plugin.name": "pgoutput",
"slot.name": "cdc_slot",
"publication.name": "my_pub"
}
}
Мониторинг
-- Отставание реплики
SELECT
client_addr,
state,
sent_lsn - replay_lsn AS byte_lag,
replay_lag
FROM pg_stat_replication;
-- Статус WAL
SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) FROM pg_stat_replication;
Заключение
Streaming replication — основа HA для PostgreSQL. Логическая репликация открывает возможности для CDC, миграций и синхронизации с другими системами. Правильное использование replication slots критично для предотвращения потери данных.