Репликация в PostgreSQL при помощи repmgr (настройка, switchover, failover)

Не так давно, мне довелось разбираться с настройкой репликации PostgreSQL при помощи утилиты repmgr. В процессе работы, я столкнулся с тем, что не смог найти полного гайда по настройке и выполнению switchover и failover в различных ситуациях. В итоге, я написал для себя инструкцию, надеюсь она будет полезна тем, кто решит управлять репликацией в PostgreSQL при помощи инструмента repmgr.

Легенда

У нас имеется 3 сервера:

Имя сервера Роль сервера ОС ПО
srvdb1 Primary CentOS 7 PostgreSQL 11, Repmgr 4.2
srvdb2 Standby CentOS 7 PostgreSQL 11, Repmgr 4.2
srvbcp Backup CentOS 7 Barman 2.5

Настройка repmgr

Полезные ссылки:
https://repmgr.org/docs/4.2/quickstart-postgresql-configuration.html

https://medium.com/coderbunker/implement-replication-with-repmgr-and-barman-f1643d3ba9b7

https://medium.com/coderbunker/failover-with-repmgr-and-automatic-failover-implementation-357278cb35d2

Устанавливаем repmgr:

sudo yum install repmgr11

У пользователя postgres должны быть права на запись и правку конфигов в /etc/repmgr.
Порты 5432 на primary и standby должны быть доступны по сети.

Правим конфиг postgresql.conf на primary (srvdb1):

В версиях PostgreSQL 9.6 и выше прописываем — wal_level = replica, в версиях ниже 9.6 прописываем — wal_level = hot_standby

listen_addresses = '*'
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
host_standby = on
archive_mode = on
archive_command = '/bin/true'
wal_keep_segments = 16

В pg_hba.conf разрешаем сетевые подключения и подключения для repmgr:

host all all 0.0.0.0/0 md5
host replication repmgr srvdb2 md5

Из под пользователя postgres создаем юзера и базу:

createuser -s repmgr
createdb repmgr -O repmgr

Выполняем команды:

ALTER USER repmgr WITH ENCRYPTED PASSWORD 'password';
ALTER USER repmgr SET search_path TO repmgr, "$user", public;

На primary и standby добавляем в файл для хранения паролей postgres/.pgpass (домашняя директория postgres ~):

# hostname:port:database:username:password
*:*:*:repmgr:password

Изменяем на него права:

chmod 600 ~/.pgpass

Проверяем подключение со standby сервера:

psql -c 'select version()' -U repmgr -h srvdb1 postgres
psql -U repmgr -h srvdb001 -c "IDENTIFY_SYSTEM" replication=1

На primary в файле /etc/repmgr/11/repmgr.conf задаем (прочие параметры не меняем):

node_id=1
node_name=srvdb1
conninfo='host=srvdb1 dbname=repmgr user=repmgr'
data_directory='/postgres/data/'
use_replication_slots=1
pg_bindir='/usr/pgsql-11/bin/'
log_file='/var/log/repmgr/repmgr-11.log'

Если для управления PostgreSQL используется systemd, а не pg_ctl, необходимо настроить в конфиге repmgr команды управления, как описано ниже в пункте «Дополнительная информация»

При переходе на 4-ю версию в repmgr были переименованы некоторые параметры конфига, часть параметров более неподдерживается.Более подробно тут https://repmgr.org/docs/4.2/upgrading-from-repmgr-3.html

На всякий случай, перед инициализацией repmgr, в /etc/repmgr/11/repmgr.conf лучше включить режим log_level=DEBUG, т.к. иногда на этом этапе возникают проблемы с инициализацией.

На primary инициализируем repmgr:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf master register

Должны появиться сообщения вида:

INFO: connecting to primary database...
DEBUG: connecting to: "user=repmgr dbname=repmgr host=srvdb1 connect_timeout=2 fallback_application_name=repmgr"
NOTICE: attempting to install extension "repmgr"
NOTICE: "repmgr" extension successfully installed
NOTICE: primary node record (id: 1) registered

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

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

В бд можно выполнить запрос:

SELECT * FROM repmgr.nodes;

На standby правим конфиг repmgr:

node_id=2
node_name=srvdb2
conninfo='host=srvdb2 dbname=repmgr user=repmgr'
data_directory='/postgres/data/'
use_replication_slots=1
pg_bindir='/usr/pgsql-11/bin/'
log_file='/var/log/repmgr/repmgr-11.log'

Запускаем на standby клонирование мастера в тестовом режиме с параметром —dry-run:

/usr/pgsql-11/bin/repmgr -h srvdb001 -U repmgr -d repmgr -f /etc/repmgr/11/repmgr.conf standby clone --dry-run

Должны появиться записи вида:

NOTICE: destination directory "/postgres/data/" provided
INFO: connecting to source node
DETAIL: connection string is: host=srvdb1 user=repmgr dbname=repmgr
DETAIL: current installation size is 1638 MB
NOTICE: standby will attach to upstream node 1
HINT: consider using the -c/--fast-checkpoint option
INFO: all prerequisites for "standby clone" are met

Если все ОК, то запускаем на standby клонирование данных:

/usr/pgsql-11/bin/repmgr -h srvdb1 -U repmgr -d repmgr -f /etc/repmgr/11/repmgr.conf standby clone

Должны появиться записи вида:

NOTICE: destination directory "/postgres/data" provided
INFO: connecting to source node
DETAIL: connection string is: host=srvdb1 user=repmgr dbname=repmgr
DETAIL: current installation size is 1640 MB
INFO: checking and correcting permissions on existing directory"/postgres/data"NOTICE: starting backup (using pg_basebackup)...
HINT: this may take some time; consider using the -c/--fast-checkpointoption
INFO: executing:/usr/pgsql-11/bin/pg_basebackup -l "repmgr base backup" -D /postgres/data-h srvdb1 -p 5432 -U repmgr -X stream -S repmgr_slot_2
NOTICE: standby clone (using pg_basebackup) complete
NOTICE: you can now start your PostgreSQL serverHINT: for example: pg_ctl -D /postgres/data start
HINT: after starting the server, you need to register this standby with"repmgr standby register"

На standby вносим специфичные изменения в конфиги. Например, в $PGDATA/pg_hba.conf необходимо разрешить подключения дляrepmgr c primary (для switchover):

host replication repmgr srvdb001.rccf.ru md5

Запускаем PostgreSQL:

sudo /bin/systemctl start postgresql-11

На standby регистрируем repmgr в БД:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby register

Должны появиться записи вида:

INFO: connecting to local node "srvdb2" (ID: 2)
INFO: connecting to primary database
WARNING: --upstream-node-id not supplied, assuming upstream node is primary(node ID 1)
INFO: standby registration complete
NOTICE: standby node "srvdb2" (id: 2) successfully registered

Проверяем, что в standby БД появились нужные таблицы и записи о primary и standby:

psql -d repmgr -c 'SELECT * FROM repmgr.nodes;'

Так же на standby проверяем состояние кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Для проверки, что репликация работает, на primary создаем таблицу или базу и проверяем что она появилась на standby.

Запланированное переключение primary-standby — switchover

Тестируем запланированное переключение на standby (например, в случае запланированных работ). Перед тестированием проверить что все требования соблюдены: https://repmgr.org/docs/4.2/preparing-for-switchover.html

Важно! Требуется беспарольный доступ по ssh между серверами для пользователя postgres (от него запускается repmgr). Создаем на srvdb1 сервере ключ (на все вопросы можно нажать Enter):
ssh-keygen -t rsa
Будут созданы два файла id_rsa и id_rsa.pub
Содержимое id_rsa.pub копируем на srvdb2 сервер и добавляем одной строкой в файл authorized_keys:less /var/lib/pgsql/.ssh/id_rsa.pub
(Директория ~/.ssh)
Копируем
echo «содержимое файла» >> /var/lib/pgsql/.ssh/authorized_keys
Проверяем доступ с сервера srvdb1 на srvdb2:
ssh postgres@srvdb2
Повторяем тоже самое на srvdb22 сервере (генерим на нем ключ и на srvdb1 сервер копируем в файл authorized_keys и проверяем доступ).

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

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Протестировать возможность switchover можно запустив на standby команду:

/usr/pgsql-11/bin/repmgr standby switchover -f /etc/repmgr/11/repmgr.conf--siblings-follow --dry-run

На standby запускаем команду switchover: https://repmgr.org/docs/4.2/switchover-execution.html:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby switchover

Если все успешно, значит мы переключились. Проверяем состояние кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Переключение в случае failover

Вариант с полным восстановлением бывшего primary при помощи клонирования данных с нового primary

http://tushar-postgresql.blogspot.com/2017/12/repmgr-postgresql-replication-fail-over.html
Предположим что primary (srvdb001) упал и не работает. Воспроизведем ситуацию.
Гасим primary и проверяем что в кластере он не включен. На primary (srvdb1):

sudo /bin/systemctl stop postgresql-11

На standby (srvdb2):

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Теперь поднимаем standby (srvdb2) до primary:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby promote

Должны появиться записи вида:

NOTICE: promoting standby to primary
DETAIL: promoting server "srvdb2" (ID: 2) using "/usr/pgsql-11/bin/pg_ctl-w -D '/postgres/data' promote"
DETAIL: waiting up to 60 seconds (parameter "promote_check_timeout") for promotion to complete waiting for server to promote.... done server promoted
NOTICE: STANDBY PROMOTE successful
DETAIL: server "srvdb2" (ID: 2) was successfully promoted to primary

Проверяем на новом primary (srvdb2) статус кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Теперь у нас новый primary (srvdb2):

ID | Name | Role | Status | Upstream | Location | Connection string
----+----------+---------+-----------+----------+----------+-----------------------------------------
1 | srvdb1 | primary | - failed | | default | host=srvdb1 dbname=repmgruser=repmgr
2 | srvdb2 | primary | * running | | default | host=srvdb2 dbname=repmgr user=repmgr

Создадим тестовую бд или таблицу на новом primary.
Удалим регистрацию старого primary (srvdb1):

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf primary unregister --node-id=1

И проверяем статус кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+----------+---------+-----------+----------+----------+-----------------------------------------
2 | srvdb2 | primary | * running | | default | host=srvdb2 dbname=repmgr user=repmgr

Самый простой способ вернуть старый сервер (srvdb1) — удалить его datadir и зарегистрировать заново как standby:

rm -rf /postgres/data/

Запускаем клонирование данных с нового primary (srvdb2):

/usr/pgsql-11/bin/repmgr -h srvdb2 -U repmgr -d repmgr -f/etc/repmgr/11/repmgr.conf standby clone

На новом standby (srvdb1) вносим специфичные изменения в конфиги.
Запускаем PostgreSQL:

sudo /bin/systemctl start postgresql-11

Регистрируем новый standby:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby register

Должны появиться записи вида:

INFO: connecting to local node "srvdb1" (ID: 1)
INFO: connecting to primary database
WARNING: --upstream-node-id not supplied, assuming upstream node is primary(node ID 2)
INFO: standby registration complete
NOTICE: standby node "srvdb1" (id: 1) successfully registered

Проверяем, что в standby БД появились нужные таблицы и записи о primary и standby:

psql -d repmgr -c 'SELECT * FROM repmgr.nodes;'

Так же на standby проверяем состояние кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Для проверки, что репликация работает, на primary создаем таблицу или базу и проверяем что она появилась на standby.

Вариант с поднятием старого primary и догонкой им транзакций с нового primary (болееверный вариант)

http://tushar-postgresql.blogspot.com/2017/12/repmgr-postgresql-replication-fail-over.html
Предположим что primary (srvdb001) упал и не работает. Воспроизведем ситуацию.
Гасим primary и проверяем что в кластере он не включен.На primary (srvdb1):

sudo /bin/systemctl stop postgresql-11

На standby (srvdb002):

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Теперь поднимаем standby (srvdb002) до primary:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby promote

Должны появиться записи вида:

NOTICE: promoting standby to primary
DETAIL: promoting server "srvdb2" (ID: 2) using "/usr/pgsql-11/bin/pg_ctl-w -D '/postgres/data' promote"
DETAIL: waiting up to 60 seconds (parameter "promote_check_timeout") for promotion to complete waiting for server to promote.... done server promoted
NOTICE: STANDBY PROMOTE successful
DETAIL: server "srvdb2" (ID: 2) was successfully promoted to primary

Проверяем на новом primary (srvdb2) статус кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Теперь у нас новый primary (srvdb2):

ID | Name | Role | Status | Upstream | Location | Connection string
----+----------+---------+-----------+----------+----------+-----------------------------------------
1 | srvdb1 | primary | - failed | | default | host=srvdb1 dbname=repmgr user=repmgr
2 | srvdb2 | primary | * running | | default | host=srvdb2 dbname=repmgr user=repmgr

Создадим тестовую бд или таблицу на новом primary.

Регистрацию старого primary из repmgr на новом primary НЕ УДАЛЯЕМ!
После того, как нам стал доступен старый primary, на нем PostgreSQL НЕ ЗАПУСКАЕМ, он должен быть выключен.

Заходим на сервер старого primary (srvdb1) и выполняем команду rejoin:

Команда rejoin работает только если PostgreSQL выключен.

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf node rejoin --force-rewind -d 'host=srvdb2 dbname=repmgr user=repmgr'

Должны появиться записи вида:

NOTICE: executing pg_rewind
NOTICE: 0 files copied to /postgres/data/
NOTICE: setting node 1's primary to node 2
NOTICE: starting server using "/usr/pgsql-11/bin/pg_ctl -w -D'/postgres/data/' start"
INFO: waiting for node 1 to connect to new primary; 1 of max 60 attempts
NOTICE: NODE REJOIN successful
DETAIL: node 1 is now attached to node 2

Наш старый primary (srvdb1) стал standby и теперь можно на нем проверить состояние кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Заходим на старый primary (srvdb1) и проверяем наличие тестовой бд или таблицы, которую мы создали когда он не работал.

В случае, если на старом primary уже успели запустить PostgreSQL

Останавливаем postgres:

sudo /bin/systemctl stop postgresql-11

Запускаем rejoin:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf node rejoin --force-rewind -d 'host=srvdb2 dbname=repmgr user=repmgr'

Скорее всего, мы получил сообщение об ошибке, например:

NOTICE: executing pg_rewind
NOTICE: 0 files copied to /postgres/data/
NOTICE: setting node 1's primary to node 2
NOTICE: starting server using "sudo /bin/systemctl start postgresql-11"
Job for postgresql-11.service failed because the control process exited with error code. See "systemctl status postgresql-11.service" and"journalctl -xe" for details.
ERROR: unable to start server
NOTICE: NODE REJOIN failed

В данном случае нам нужно посмотреть ошибку в журнале, или для начала ошибку через status:

sudo /bin/systemctl status postgresql-11

Вероятнее всего, из-за запуска сервиса postgres на старом primary, произошел рассинхрон двух нод. После нашей попытки выполнить rejoin, pg_rewind (вызванный параметром —force-rewind) синхронизировал ноды и на старом primary(srvdb1) мы получили те же конфиги что и на новом primary (srvdb2). Для исправления ситуации, правим конфиги postgresql.conf и pg_hba.conf.
После этого, нам необходимо запустить postgres и остановить, чтобы он успешно завершил работу:

sudo /bin/systemctl start postgresql-11
sudo /bin/systemctl stop postgresql-11

После этого запускаем rejoin повторно:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf node rejoin --force-rewind -d 'host=srvdb2 dbname=repmgr user=repmgr'

Все должно пройти успешно:

NOTICE: executing pg_rewind
NOTICE: 0 files copied to /postgres/data/
NOTICE: setting node 1's primary to node 2
NOTICE: starting server using "sudo /bin/systemctl start postgresql-11"
NOTICE: NODE REJOIN successfulDETAIL: node 1 is now attached to node 2

Дополнительная информация

Команды, которые выполняет repmgr при svitchover, rejoin, и прочие, которые затрагивают start/restart/stop/reload/promote postgres,используют pg_ctl. Список команд которые будет использовать repmgr можно посмотреть на каждой конкретной ноде выполнив:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf node service --list-actions

В ответ будет следующий список:

Following commands would be executed for each action:
start: "/usr/pgsql-11/bin/pg_ctl -w -D '/postgres/data/' start"
stop: "/usr/pgsql-11/bin/pg_ctl -D '/postgres/data/' -W -m fast stop"
restart: "/usr/pgsql-11/bin/pg_ctl -w -D '/postgres/data/' restart"
reload: "/usr/pgsql-11/bin/pg_ctl -w -D '/postgres/data/' reload"
promote: "/usr/pgsql-11/bin/pg_ctl -w -D '/postgres/data/' promote"

Эти команды можно переопределить в конфиге repmgr.conf в параметрах:

#service_start_command = ''
#service_stop_command = ''
#service_restart_command = ''
#service_reload_command = '
'#service_promote_command = ''

В системах systemd рекомендуется использовать соответствующие команды systemctl (обычно запускаемые через sudo),чтобы гарантировать, что systemd проинформирован о состоянии службы PostgreSQL.
Если используется sudo для вызовов systemctl, нужно убедиться что пользователь имеет право на вызов команд systemctl через sudo.

Например, внесем изменения в конфиг repmgr на сервер, на котором хотим использовать команды systemctl:

service_start_command = 'sudo /bin/systemctl start postgresql-11'
service_stop_command = 'sudo /bin/systemctl stop postgresql-11'
service_restart_command = 'sudo /bin/systemctl restart postgresql-11'
service_reload_command = 'sudo /bin/systemctl reload postgresql-11'
#service_promote_command = ''

Проверим что команды верные:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf node service --list-actions

Мы должны получить следующее:

Following commands would be executed for each action:
start: "sudo /bin/systemctl start postgresql-11"
stop: "sudo /bin/systemctl stop postgresql-11"
restart: "sudo /bin/systemctl restart postgresql-11"
reload: "sudo /bin/systemctl reload postgresql-11"
promote: "/usr/pgsql-11/bin/pg_ctl -w -D '/postgres/data/' promote"

Важно: если у нас уже запущен postgres при помощи pg_ctl, то сначала нужно его остановить при помощи pg_ctl и запустить через systemctl.

/usr/pgsql-11/bin/pg_ctl stop -D /postgres/data/
sudo /bin/systemctl start postgrsql-11

Теперь выполним на standby switchover:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby switchover

Команды на сервере, на котором мы изменили конфиг, выполнятся через systemctl (если все команды верны и у пользователя естьправа на их выполнение). Например, в варианте ниже, на сервере srvdb1 настроены команды systemctl, а на сервере srvdb2 pg_ctl:

NOTICE: executing switchover on node "srvdb2" (ID: 2)
WARNING: number of pending archive files on demotion candidate "srvdb1"is warning
DETAIL: 20 pending archive files (warning threshold: 16)
HINT: PostgreSQL will not shut down until all files are archived
NOTICE: local node "srvdb2" (ID: 2) will be promoted to primary; current primary "srvdb1" (ID: 1) will be demoted to standby
NOTICE: stopping current primary node "srvdb1" (ID: 1)
NOTICE: issuing CHECKPOINT
DETAIL: executing server command "sudo /bin/systemctl stop postgresql-11"
INFO: checking for primary shutdown; 1 of 60 attempts("shutdown_check_timeout")
NOTICE: current primary has been cleanly shut down at location A8D/C5000028
NOTICE: promoting standby to primary
DETAIL: promoting server "srvdb2" (ID: 2) using "/usr/pgsql-11/bin/pg_ctl-w -D '/postgres/data' promote"
DETAIL: waiting up to 60 seconds (parameter "promote_check_timeout") for promotion to complete waiting for server to promote.... done server promoted
NOTICE: STANDBY PROMOTE successful
DETAIL: server "srvdb2" (ID: 2) was successfully promoted to primary
NOTICE: setting node 1's primary to node 2
NOTICE: starting server using "sudo /bin/systemctl start postgresql-11"
NOTICE: replication slot "repmgr_slot_2" deleted on node 1
NOTICE: NODE REJOIN successful
DETAIL: node 1 is now attached to node 2
NOTICE: switchover was successful
DETAIL: node "srvdb2" is now primary and node "srvdb1" is attached asstandby
NOTICE: STANDBY SWITCHOVER has completed successfully

Если все успешно, значит мы переключились. Проверяем состояние кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Настройка Repmgr через Barman

https://www.pgbarman.org/

Используются бекапы Barman и получаемые WAL логи для первичной инициализации standby и синхронизации standby в случае ее длительного отключения. Преимущества — нет нагрузки на primary во время клонирования при инициализации реплики, логи не копятся на primary в случае длительного выключения standby, не требуется хранение wal_keep_segments. Т.е. бекапы Barman используются как резерв для репликации.
Все действия на серверах БД производятся под учеткой postgres, на barman сервере — под учеткой barman.

Правим конфиг postgresql.conf на primary (srvdb1):

listen_addresses = '*'
wal_level = replic
amax_wal_senders = 10
max_replication_slots = 10
hot_standby = on
archive_mode = on
archive_command = '/bin/true'
wal_keep_segments = 16

В pg_hba.conf разрешаем сетевые подключения и подключения для repmgr и barman:

host all all 0.0.0.0/0 md5
host replication repmgr srvdb2 md5
host replication barman srvbcp md5

Настраиваем бекап wal с помощью barman (механизм потоковой репликации). На master создаем юзера barman:

createuser -s -W barman

И выдаем ему пароль:

alter user barman password 'password';

Настраиваем беспарольный ssh (уже описывалось в инструкции выше) между тремя серверами srvdb1, srvdb1 и srvbcp, так чтобы:

  • пользователь postgres мог подключаться с primary и standby к серверу backup (srvabcp)
  • пользователь barman мог подключаться с сервера backup (srvap003) к серверам primary и standby

Записываем в файл паролей учетки barman: ~/.pgpass на backup сервере:

# hostname:port:database:username:password
*:*:*:barman:password

И меняем права к файлу:

chmod 600 ~/.pgpass

Проверяем подключение с сервера backup (srvbcp) к серверу primary (srvdb1):

Для использования утилиты psql, на сервере backup предварительно нужно поставить пакет postgresql11-server

psql -c 'select version()' -U barman -h barsdbprod postgres
psql -U barman -h barsdbprod -c "IDENTIFY_SYSTEM" replication=1

Создаем файл конфигурации бекапа данного кластера PostgreSQL /etc/barman.d/testprod.conf примерно следующего содержания (все указываемые пути предварительно нужно создать):

[testprod]
description = "TEST PROD PostgreSQL server 11"
conninfo = host=srvdb1 user=barman dbname=postgres
streaming_conninfo = host=srvdb11 user=barman
backup_method = postgres
streaming_archiver = on
slot_name = barman
;backup_options = concurrent_backup
streaming_wals_directory = /mnt/pgbackup/testprod/streaming_wals
backup_directory = /mnt/pgbackup/testprodbase
backups_directory = /mnt/pgbackup/testprod/base
errors_directory = /mnt/pgbackup/testprod/errors
incoming_wals_directory = /mnt/pgbackup/testprod/incoming
wals_directory = /mnt/pgbackup/testprod/wals
path_prefix = /usr/pgsql-11/bin

В параметре conninfo вместо конкретного хоста лучше указать DNS имя всего кластера (до этого нужно создать это DNS-имя и прописать ему адрес primary сервера), чтобы не требовалось менять хост после switchover или failover переключения

Создаем репликационный слот в БД для потоковой репликации:

barman@srvbcp:~$ barman receive-wal --create-slot barsprod

Проверяем сообщения в логе /var/log/barman/barman.log, там должны быть надписи вида:

2016-11-29 16:03:43,135 [34765] barman.server INFO: Creating physicalreplication slot 'barman' on server 'barsprod'2016-11-29 16:03:43,145 [34765] barman.server INFO: Replication slot'barman' created

Также проверяем, что появляются файлы логов в директории для бекапа:

barman show-server testprod | grep streaming_wals_directory

Увидим ответ:

streaming_wals_directory: /mnt/pgbackup/testprod/streaming_wals
ls -l /mnt/pgbackup/testprod/streaming_wals

Ответ должен быть вида:

total 16456
-rw------- 1 barman barman 16777216 Nov 29 16:06000000010000000000000001.partial

Если в логе ошибки, то проверяем настройки:

barman check testprod
barman show-server testprod

И вносим коррективы в конфиг /etc/barman.d/testprod.conf
Создаем полный бэкап БД:

barman backup testprod

Если выдает ошибку: то необходимо ERROR: Impossible to start the backup. Check the log for more details, or run ‘barman check testprod’ выполнить:

barman switch-xlog --force testprod

Подробное описание здесь: https://groups.google.com/forum/#!topic/pgbarman/M-eFUCA1nHA
Затем, заново запускаем бекап (может сработать не с первого раза, если WAL лог прилетит с задержкой):

barman backup testprod

Проверяем, что бекап виден:

barman list-backup testprod
testprod 20161201T163405 - Thu Dec 1 16:34:05 2016 - Size: 37.9 MiB - WALSize: 16.0 MiB

Детализированная информация:

barman show-backup testprod 20161201T163405
barman list-files testprod 20161201T163405

Устанавливаем на primary и standby сервера: repmgr (Replication Manager for PostgreSQL Clusters), barman-cli и rsync:

sudo yum install repmgr11 barman-cli rsync

У postgres должны быть права на запись и правку конфигов в /etc/repmgrПорты 5432 на primary и standby должны быть доступны по сети.

Из под пользователя postgres создаем юзера и базу:

createuser -s repmgr
createdb repmgr -O repmgr

Выполняем команды:

ALTER USER repmgr PASSWORD 'password';
ALTER USER repmgr SET search_path TO repmgr, "$user", public;

На primary и standby добавляем в файл для хранения паролей postgres/.pgpass (домашняя директория postgres ~):

# hostname:port:database:username:password
*:*:*:repmgr:password

Изменяем на него права:

chmod 600 ~/.pgpass

Проверяем подключение со standby сервера:

psql -c 'select version()' -U repmgr -h srvdb1 postgres
psql -U repmgr -h srvdb1 -c "IDENTIFY_SYSTEM" replication=1

Далее выполним клонирование и репликация standby БД через barman и repmgr.

Внимание! Предварительно должен быть сделан хотя бы 1 полный бэкап средствами barman.

На primary в файле /etc/repmgr/11/repmgr.conf задаем (прочие параметры не меняем):

node_id=1
node_name=srvdb1
conninfo='host=srvdb1 dbname=repmgr user=repmgr'
data_directory='/postgres/data/'
use_replication_slots=1
pg_bindir='/usr/pgsql-11/bin/'
restore_command='/usr/bin/barman-wal-restore srvbcp testprod %f %p'
barman_server='testprod'
barman_host='srvbcp'
log_file='/var/log/repmgr/repmgr-11.log'

На всякий случай, перед инициализацией repmgr, в /etc/repmgr/11/repmgr.conf лучше включить режим log_level=DEBUG, т.к. иногда возникают проблемы с инициализацией.

На primary инициализируем repmgr:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf master register

Должны появиться сообщения вида:

INFO: connecting to primary database...
DEBUG: connecting to: "user=repmgr dbname=repmgr host=srvdb1 connect_timeout=2 fallback_application_name=repmgr"
NOTICE: attempting to install extension "repmgr"
NOTICE: "repmgr" extension successfully installed
NOTICE: primary node record (id: 1) registered

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

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

В бд можно выполнить запрос:

SELECT * FROM repmgr.nodes;

На standby правим конфиг repmgr:

node_id=2
node_name=srvdb2
conninfo='host=srvdb2 dbname=repmgr user=repmgr'
data_directory='/postgres/data/'
use_replication_slots=1
pg_bindir='/usr/pgsql-11/bin/'
restore_command='/usr/bin/barman-wal-restore srvbcp testprod %f %p'
barman_server='testprod'
barman_host='srvbcp'
log_file='/var/log/repmgr/repmgr-11.log'

На primary и standby в ~/.ssh/config прописываем:

Файл ~/.ssh/barman_key необходимо создать заранее, как уже описывалось с ключами ранее, только указав файлы «barman» для ключей

Host srvbcp
User barman
IdentityFile ~/.ssh/barman_key

Проверяем, что ssh barman@srvbcp проходит с обоих серверов БД без пароля.
Запускаем на standby клонирование мастера в тестовом режиме с параметром —dry-run:

/usr/pgsql-11/bin/repmgr -h srvdb1 -U repmgr -d repmgr -f /etc/repmgr/11/repmgr.conf standby clone --dry-run

Должны появиться записи вида:

NOTICE: destination directory "/postgres/data/" provided
INFO: connecting to source node
DETAIL: connection string is: host=srvdb1 user=repmgr dbname=repmgr
DETAIL: current installation size is 1638 MB
NOTICE: standby will attach to upstream node 1
HINT: consider using the -c/--fast-checkpoint option
INFO: all prerequisites for "standby clone" are met

Если все ОК, то запускаем на slave клонирование данных:

/usr/pgsql-11/bin/repmgr -h srvdb1 -U repmgr -d repmgr -f /etc/repmgr/11/repmgr.conf standby clone

Должны появиться записи вида:

[NOTICE] destination directory '/postgres/data' provided
[INFO] Connecting to Barman server to verify backup for testprod
[INFO] creating directory "/postgres/data/repmgr"...
[INFO] Connecting to Barman server to fetch server parameters
[INFO] connecting to upstream node
[INFO] Successfully connected to upstream node. Current installation sizeis 29 MB
[NOTICE] getting backup from Barman...
[DEBUG] create_recovery_file(): creating '/postgres/data/recovery.conf'...
[DEBUG] recovery.conf: standby_mode = 'on'
[DEBUG] recovery.conf: primary_conninfo = 'user=repmgr port=5432 sslmode=prefer sslcompression=1 krbsrvname=postgres host=srvdb1 application_name=srvdb2 password=...'
[DEBUG] recovery.conf: recovery_target_timeline = 'latest'
[DEBUG] recovery.conf: restore_command = '/usr/bin/barman-wal-restore srvbcp testprod %f %p'
[NOTICE] standby clone (from Barman) complete
[NOTICE] you can now start your PostgreSQL server
[HINT] for example : pg_ctl -D /postgres/data start
[HINT] After starting the server, you need to register this standby with"repmgr standby register"

На standby вносим специфичные изменения в конфиги. Например, в $PGDATA/pg_hba.conf необходимо разрешить подключения для repmgr c primary (для switchover):

host replication repmgr srvdb1 md5

Запускаем PostgreSQL:

sudo /bin/systemctl start postgresql-11

На standby регистрируем repmgr в БД:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf standby register

Должны появиться записи вида:

INFO: connecting to local node "srvdb2" (ID: 2)
INFO: connecting to primary database
WARNING: --upstream-node-id not supplied, assuming upstream node is primary(node ID 1)
INFO: standby registration complete
NOTICE: standby node "srvdb2" (id: 2) successfully registered

Проверяем, что в standby БД появились нужные таблицы и записи о primary и standby:

SELECT * FROM repmgr.nodes;

Так же на standby проверяем состояние кластера:

/usr/pgsql-11/bin/repmgr -f /etc/repmgr/11/repmgr.conf cluster show

Для проверки, что репликация работает, на primary создаем таблицу или базу и проверяем что она появилась на standby.
На primary проверяем статус репликации:

SELECT * FROM pg_stat_replication;

Мы должны увидеть 2 записи — одну для barman, другую для repmgr:

SELECT * FROM pg_replication_slots;
3+

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

Ваш e-mail не будет опубликован.