ADG Оставить заявку
Блог Данные и аналитика 5 мин чтения

PostgreSQL streaming replication + repmgr: дешёвый HA без коммерческих лицензий

Настраиваем PostgreSQL streaming replication с hot standby и автоматическим failover через repmgr: standby читает production, переключение при падении мастера - ~30 секунд.

Контекст момента

PostgreSQL streaming replication + hot standby как замена дорогим коммерческим HA-решениям

Когда клиент в феврале обозначил, что хочет уйти с Oracle SE на PostgreSQL, одним из первых вопросов стало: «а что с отказоустойчивостью?». Oracle SE без дорогих опций в этом месте слабоват - нормальный RAC стоит денег, которые и без того освобождаются при переходе. PostgreSQL предлагает streaming replication прямо из коробки. Мы разбирали это в плане миграции, а теперь дошли до практики.

Что мы настраивали

Стенд: мастер (CentOS 7, PostgreSQL 9.4) и один standby на отдельной машине в той же сети. Дополнительно - утилита repmgr от 2ndQuadrant для мониторинга состояния кластера и автоматического failover. Задача: standby должен читать production-нагрузку (аналитические запросы, отчёты), а при падении мастера переключиться с минимальным окном недоступности.

Streaming replication: механика

PostgreSQL пишет все изменения в WAL (Write-Ahead Log) перед применением к данным. Streaming replication - это когда standby подключается к мастеру как обычный клиент, но по специальному replication-протоколу, и получает поток WAL-записей в реальном времени, применяя их у себя.

Hot standby - режим в котором standby принимает SELECT-запросы прямо во время воспроизведения WAL. Это не отдельная фича поверх репликации, а встроенный режим работы: пока воспроизводится WAL, читать данные можно, но только те которые уже зафиксированы.

Настройка на мастере (postgresql.conf):

wal_level = hot_standby
max_wal_senders = 3
wal_keep_segments = 32

В pg_hba.conf добавляется строка, разрешающая replication-соединение с IP standby. На standby создаётся recovery.conf с указанием мастера:

standby_mode = on
primary_conninfo = 'host=master-ip port=5432 user=replicator password=...'
hot_standby = on

Запускаешь standby через pg_basebackup - он снимает консистентную копию с мастера и сразу ставит в режим ожидания. Если всё настроено, через несколько секунд видишь в логах standby: started streaming WAL from primary. Это приятный момент.

Лаг репликации видно через системное представление pg_stat_replication на мастере - там показывается задержка в байтах и времени между тем что записано на мастере и что уже применено на standby. На нашем стенде при умеренной write-нагрузке лаг держался в пределах секунды.

Hot standby и конфликты

Здесь есть нюанс который не сразу очевиден. WAL на мастере может содержать операции vacuum - очистку мёртвых строк. Если на standby в это время работает длинный SELECT, который держит снимок данных, и vacuum на мастере хочет убрать строки которые этот SELECT ещё «видит» - возникает конфликт репликации. PostgreSQL по умолчанию отменяет запрос на standby (max_standby_streaming_delay).

Для аналитических запросов которые могут работать долго это важно: нужно настроить max_standby_streaming_delay или hot_standby_feedback = on. Второй параметр говорит standby сообщать мастеру какой снимок данных сейчас активен - мастер учитывает это при vacuum. Есть обратная сторона: раздувание таблиц на мастере если standby держит длинные транзакции. Мы остановились на hot_standby_feedback = on и следим за bloat мастера.

repmgr: автоматический failover

Репликация сама по себе не делает failover. Если мастер упал - standby продолжает воспроизводить WAL из буфера, потом ждёт. Клиенты получают ошибки соединения. Нужен кто-то кто заметит отказ и переключит standby в режим мастера.

repmgr - утилита именно для этого. Устанавливается на оба сервера, в конфиге описывается топология кластера. Демон repmgrd мониторит состояние мастера: периодически коннектится и проверяет доступность. При недоступности - инициирует промоушн standby.

Команда промоушна вручную выглядит просто:

repmgr standby promote

После неё standby переходит в режим мастера - PostgreSQL переходит в read-write, создаёт новый timeline в WAL. Клиентам нужно переподключиться к новому мастеру. Автоматически это делает repmgrd: при обнаружении отказа мастера он выполняет промоушн и уведомляет (через скрипт, который мы написали) систему мониторинга и меняет запись в конфигурации балансировщика.

На практике мы несколько раз имитировали падение мастера через kill -9 процесса PostgreSQL. repmgrd обнаруживал проблему примерно за 15-20 секунд (зависит от reconnect_attempts и reconnect_interval), промоушн занимал ещё несколько секунд. Итого от момента гибели мастера до появления нового читаемого и пишущего PostgreSQL - около 30 секунд.

Это не нулевое RTO, но для большинства задач DWH вполне приемлемо. Сравните с ценником Oracle Data Guard.

Что с обратным восстановлением старого мастера

Это отдельная операция, которую repmgr тоже поддерживает: repmgr standby clone - старый мастер клонируется с нового мастера и подключается как standby нового кластера. Потом можно при необходимости сделать обратный switchover. Мы проверили - работает, но требует внимательности: timeline в WAL сменился, и старый мастер должен синхронизировать историю с нового.

Нагрузка на standby

Аналитические запросы с отчётностью мы направили на standby через изменение строки подключения в reporting-инструменте. Нагрузка - SELECT-ы к витринам, несколько параллельных сессий. Standby держит нормально: WAL-лаг от этого не растёт, производительность запросов сопоставима с мастером (те же данные, тот же планировщик).

Единственное ограничение: нельзя создавать временные таблицы при hot_standby_feedback = on на старых версиях - в 9.4 это починили. Мы писали о 9.4 в январе, там же про другие улучшения для аналитики.

Итог

Streaming replication + hot standby в PostgreSQL 9.4 - рабочий HA без коммерческих надстроек. repmgr добавляет автоматический failover и управление топологией. Настройка занимает день, включая тестирование отказовых сценариев.

Основные грабли:

  • Конфликты репликации при длинных SELECT на standby - решается hot_standby_feedback, но надо следить за bloat.
  • Failover не мгновенный - около 30 секунд, что нужно учитывать в SLA.
  • Обратный switchover требует ручного клонирования старого мастера.

Для задач DWH и аналитики схема «мастер + читающий standby с автофайловером» закрывает основные требования без Oracle-ценника.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.