Настройка репликации 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 — это дополнительный уровень защиты, но не обязателен.

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

Настройка кластера Kubernetes в Ubuntu Linux 24.04: три узла (один мастер с возможностью запуска пользовательских подов, PVC в каталоге на хосте, сеть на Calico)

В этой статье мы рассмотрим пошаговую настройку кластера Kubernetes на Ubuntu 24.04 с тремя узлами: один мастер (который также может запускать пользовательские поды) и два рабочих узла. Мы настроим PersistentVolume…

Инструкция по установке и настройке ProxySQL в Ubuntu 24.04

В рамках создания собственного кластера Kubernetes я поднаял кластер Mysql который работает в режиме Master-Slave и Slave-узлы соответственно работают в режиме read-only, а мастер в read-write. Соответственно мне нужен балансировщик…

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

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

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

Настройка кластера Kubernetes в Ubuntu Linux 24.04: три узла (один мастер с возможностью запуска пользовательских подов, PVC в каталоге на хосте, сеть на Calico)

Настройка кластера Kubernetes в Ubuntu Linux 24.04: три узла (один мастер с возможностью запуска пользовательских подов, PVC в каталоге на хосте, сеть на Calico)

Инструкция по установке и настройке ProxySQL в Ubuntu 24.04

Инструкция по установке и настройке ProxySQL в Ubuntu 24.04

Полное руководство по настройке UFW в Ubuntu: от основ до продвинутых правил

Полное руководство по настройке UFW в Ubuntu: от основ до продвинутых правил

Полное руководство по развертыванию GlusterFS в Ubuntu Linux: от подготовки до тестирования производительности

Полное руководство по развертыванию GlusterFS в Ubuntu Linux: от подготовки до тестирования производительности

Подробная инструкция по настройке кластера из трёх серверов MySQL на Ubuntu 24.04

Подробная инструкция по настройке кластера из трёх серверов MySQL на Ubuntu 24.04

Полное руководство по настройке NFS-клиента в Ubuntu Linux: от установки до автоматического монтирования

Полное руководство по настройке NFS-клиента в Ubuntu Linux: от установки до автоматического монтирования