Настройка репликации PostgreSQL в Docker (два инстанса)

Задача довольно типовая, но мы немного усложним условия и сделаем репликацию двух инстансов PostgreSQL, запущенных в Docker-контейнерах.

Что такое репликация?
Репликация — это механизм синхронизации данных между несколькими серверами баз данных. В нашем случае один сервер будет мастером (primary), который принимает все изменения, а второй — репликой (standby), которая получает и применяет эти изменения. Это обеспечивает отказоустойчивость и возможность распределения нагрузки на чтение.

Почему Docker?
Docker упрощает развёртывание и управление приложениями. Мы будем использовать два контейнера: один для мастера, другой для реплики. Все операции выполняются внутри контейнеров или снаружи с помощью docker exec.


Операции на мастер-хосте (primary)

Первым делом создадим пользователя, от имени которого будет осуществляться репликация. Этот пользователь должен иметь права на репликацию (логин и атрибут REPLICATION).

# Заходим в контейнер с PostgreSQL
docker exec -it postgresql /bin/bash

# Переключаемся на пользователя postgres (внутри контейнера)
su postgres

# Запускаем psql
psql

# Создаём роль для репликации
postgres=# CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'P@SSWORD';
postgres=# \q

# Выходим из оболочки postgres
exit

# Выходим из контейнера
exit

Пояснение:

  • REPLICATION — специальный атрибут, разрешающий подключение для потоковой репликации.
  • Пароль 'P@SSWORD' нужно заменить на свой надёжный пароль.

Теперь в файле pg_hba.conf разрешим подключение этому пользователю с хоста, где будет располагаться реплика (slave). Добавьте строку:

host  replication   replica_user   10.77.111.108/32   md5

Что это значит?

  • host — тип подключения (TCP/IP).
  • replication — специальная база данных для репликации.
  • replica_user — имя пользователя.
  • 10.77.111.108/32 — IP-адрес реплики (замените на свой).
  • md5 — метод аутентификации по паролю.

Далее вносим правки в конфигурационный файл PostgreSQL (обычно postgresql.conf). Нам нужно включить логический уровень WAL и подсказки для восстановления:

wal_level = logical
wal_log_hints = on

Пояснение:

  • wal_level = logical — позволяет использовать логическую репликацию (хотя для потоковой физической репликации достаточно replica, но logical даёт больше возможностей).
  • wal_log_hints = on — включает запись «подсказок» в WAL, что помогает избежать повреждений при восстановлении.

Так как мы используем контейнер, перезагрузка службы PostgreSQL выполняется иначе, чем на обычном сервере. Вместо systemctl reload используем pg_ctl reload внутри контейнера:

docker exec -it postgresql /bin/bash
su postgres
pg_ctl reload
exit
exit

Примечание: pg_ctl reload перечитывает конфигурацию без остановки сервера.


Операции на slave-хосте (реплика)

На хосте, где будет работать реплика, выполняем следующие шаги.

  1. Останавливаем контейнер с PostgreSQL (если он запущен).
    В примере используется алиас dc для docker-compose:
   dc stop postgresql
  1. Запускаем контейнер в интерактивном режиме, чтобы выполнить команды внутри:
   dc run postgresql /bin/bash
  1. Удаляем существующую базу данных (если она есть). Каталог данных PostgreSQL обычно находится в /var/lib/postgresql/data/. Удаляем всё содержимое:
   rm -rf /var/lib/postgresql/data/*
  1. Копируем базу данных с мастер-узла с помощью утилиты pg_basebackup. Эта команда создаёт точную копию данных мастера и автоматически настраивает реплику.
   pg_basebackup -h 10.51.0.100 -U replica_user -X stream -C -S replica_1 -v -R -W -D /var/lib/postgresql/data/

Разберём параметры:

  • -h 10.51.0.100 — IP-адрес мастера (замените на свой).
  • -U replica_user — пользователь для репликации.
  • -X stream — включить потоковую передачу WAL-файлов.
  • -C — создать контрольную точку (checkpoint) на мастере.
  • -S replica_1 — имя слота репликации (слот должен быть заранее создан на мастере, иначе команда упадёт).
  • -v — подробный вывод.
  • -R — создать файл standby.signal для запуска в режиме реплики.
  • -W — дождаться завершения записи WAL.
  • -D /var/lib/postgresql/data/ — целевой каталог для данных. Важно: Слот репликации replica_1 нужно предварительно создать на мастере:
   SELECT pg_create_physical_replication_slot('replica_1');
  1. Выходим из контейнера и запускаем контейнер в обычном режиме:
   exit
   dc start postgresql

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

Зайдите в контейнер реплики и выполните запрос к мастеру (или к реплике, но статус репликации виден на мастере). Лучше проверить на мастере:

docker exec -it postgresql_master /bin/bash
su postgres
psql

Выполните:

SELECT client_addr, state FROM pg_stat_replication;

Пример вывода:

 client_addr  |   state
--------------+------------
 10.77.111.108 | streaming
(1 row)

Что означает state = streaming?
Это значит, что реплика активна и непрерывно получает изменения с мастера.


Опционально: создаём общее хранилище WAL-файлов

Для дополнительной надёжности можно организовать общее NFS-хранилище для WAL-файлов. Это позволит реплике восстанавливаться даже при временной недоступности мастера.

Настройка NFS (по инструкции «Настройка NFS клиент-сервер в CentOS»). Смонтируйте NFS-шару в каталог /mnt/nfs на обоих хостах (мастере и реплике). Внутри создайте подкаталог /mnt/nfs/wal.

Добавляем том монтирования в контейнерdocker-compose.yml или при запуске):

volumes:
  - /mnt/nfs/wal:/wal

Теперь настраиваем архивацию WAL на мастере. В postgresql.conf мастера добавьте:

archive_mode = on
archive_command = 'test ! -f /mnt/nfs/wal/%f && cp %p /mnt/nfs/wal/%f'

Пояснение:

  • archive_mode = on — включает архивацию.
  • archive_command — копирует каждый завершённый WAL-файл в общую NFS-папку, если его там ещё нет.

На реплике (slave) добавляем параметры для восстановления из архива и очистки старых файлов:

restore_command = 'cp /mnt/nfs/wal/%f %p'
archive_cleanup_command = 'pg_archivecleanup /mnt/nfs/wal/ %r'

Что они делают?

  • restore_command — при необходимости реплика может восстановить недостающий WAL из общего хранилища.
  • archive_cleanup_command — автоматически удаляет устаревшие WAL-файлы из хранилища, чтобы не забивать диск.

После внесения изменений не забудьте перезагрузить конфигурацию на обоих серверах (pg_ctl reload).


Итог

Мы настроили потоковую репликацию PostgreSQL в Docker с использованием слота репликации и опционально — общего NFS-хранилища для WAL. Такая конфигурация обеспечивает отказоустойчивость и позволяет быстро восстановить реплику в случае сбоя.

Основные моменты:

  • Пользователь для репликации должен иметь атрибут REPLICATION.
  • pg_basebackup с ключом -R автоматически создаёт файл standby.signal.
  • Слот репликации гарантирует, что мастер не удалит нужные WAL-файлы, пока реплика их не получит.
  • Общее NFS-хранилище для WAL — это дополнительный уровень защиты, но не обязателен.

Похожие записи

Установка и оптимизация WordPress на Ubuntu 24.04 (LEMP + Redis) на VPS с ограниченным объёмом RAM

Пакеты в Ubuntu по умолчанию настроены на работу с серверами, имеющими довольно много оперативной памяти. Нам нужно жёстко ограничить потребление памяти для работы на Mikro VPS. Запускать будем мой блог…

ProxyChains специфическая работа с прокси-серверами в UNIX/Linux-системах

В современном мире, где вопросы конфиденциальности и безопасности в сети становятся всё более актуальными, инструменты для работы с прокси-серверами приобретают особую ценность. Одним из таких инструментов является программа ProxyChains, которая…

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Читать еще статьи

Интеграция Nextcloud с Keycloak через OpenID Connect: пошаговое руководство по настройке SSO

Интеграция Nextcloud с Keycloak через OpenID Connect: пошаговое руководство по настройке SSO

Установка и оптимизация WordPress на Ubuntu 24.04 (LEMP + Redis) на VPS с ограниченным объёмом RAM

Установка и оптимизация WordPress на Ubuntu 24.04 (LEMP + Redis) на VPS с ограниченным объёмом RAM

Интеграция Gitea и Keycloak: пошаговое руководство

Интеграция Gitea и Keycloak: пошаговое руководство

Настройка VS Code AI Chat для работы со сторонним OpenAI провайдером.

Настройка VS Code AI Chat для работы со сторонним OpenAI провайдером.

ProxyChains специфическая работа с прокси-серверами в UNIX/Linux-системах

ProxyChains специфическая работа с прокси-серверами в UNIX/Linux-системах

Полное руководство по установке и настройке мониторинга с Grafana и Prometheus: от установки до первого дашборда

Полное руководство по установке и настройке мониторинга с Grafana и Prometheus: от установки до первого дашборда