Linux DevOps

Репликация Postgresql 10 (Hot standby в другом ДЦ)

27.10.2019

Итак. На примере Важной Базы данных Postgresql попробую описать процесс поднятия.

Исходные данные. На обоих серверах стоит ubuntu 16.04 , а также стоит классический postgresql-10  (10.5 если быть точным).

Слейв обязательно видит мастер, мастер может быть за VPN и не видеть слейва.

На мастер сервере:

В файл /etc/postgresql/postgresql.conf добавляем следующие значения:

# replicationwal_level = replica # для посгри 9.6 и выше ставим это значение
archive_mode = on # включаем архивирование.
archive_command = 'true' # Указываем что выполнять при архивировании. тут просто true, потом можно сделать архив логов на s3 через wal-g
max_wal_senders = 10 # сколько слейвов может быть (сколько потоков)
max_replication_slots = 10 # сколько слейвов может быть (сколько потоков)
wal_keep_segments = 512 # 512 * 16Mb = 8Gb (оставляем на мастере 8 Гб wal файлов, если слейвы отвалятся, можно выключить ротацию через 0, но тогда на мастере может закончиться место)

Далее, в файле /etc/postgresql/pg_hba.conf включаем доступ для внешней репликации (вместо 0.0.0.0/0 можно указать ip реплики)

# Тут разрешаем внешние коннекты всем авторизовавшимся
host       all             all                0.0.0.0/0            md5
hostssl    all             all                0.0.0.0/0            md5 
# Тут разрешаем репликацию
host       replication     replicauser        0.0.0.0/0            md5
hostssl    replication     replicauser        0.0.0.0/0            md5

Далее, выполняем под юзером postgres запросы на создание репликационного пользователя:

# su postgres -c "psql" 

postgres=# CREATE ROLE replicauser WITH REPLICATION PASSWORD '123SUPERSECUREPASSWORD!!' LOGIN;

postgres=# ALTER USER replicauser WITH ENCRYPTED PASSWORD '123SUPERSECUREPASSWORD!!';

Делаем рестарт посгри service postgresql restart


На слейв сервере:

Для начала — останавливаем полностью посгрес на слейве. 

service postgresql stop

По-умолчанию,  папка с данными десятой посгри находится тут: /var/lib/postgresql/10/main — очищаем её, если в ней есть данные.

Далее, заходим под юзером посгрес  sudo postgres и выполняем следующие действия.

# cd ~# echo "*:*:*:replicauser:123SUPERSECUREPASSWORD!!" > /var/lib/postgresql/.pgpass

# chmod 600 /var/lib/postgresql/.pgpass

# pg_basebackup -h IP_MASTER_SERVER -D "/var/lib/postgresql/10/main" -U replicauser -v -P --write-recovery-conf -X stream

Дожидаемся, пока pg_basebackup засинкает данные.

Переходим под пользователя рут и стараемся максимально засинхронизировать файлы  /etc/postgresql/postgresql.conf  и  /etc/postgresql/pg_hba.conf  на слейве с мастера. (директории конфигов и дата-директория могут отличаться, включаем мозг и делаем такие пути, как на слейве. =) )

Теперь развлекаемся с /var/lib/postgresql/10/main/recovery.conf данный файл будет создан, после успешной репликации.

Последней строкой добавляем следующее:

trigger_file = '/var/lib/postgresql/10/main/touch_me_to_promote_to_me_master'

Это позволит перевести слейв в режим мастера простым созданием файла touch_me_to_promote_to_me_master 
ИЛИ выполняем команду по промоуту:

sudo -u postgres /usr/lib/postgresql/10/bin/pg_ctl promote  -D /var/lib/postgresql/10/main/

А теперь, самое прикольное — стартуем посгрю service postgresql start
, переходим на мастер и смотрим статус репликации

--Начиная с PG10
select
client_addr as client, usename as user, application_name as name, state,
sync_state as mode,
(pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending,
(pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write,
(pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush,
(pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay,
(pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) / 1024)::int / 1024 as
total_lag
from pg_stat_replication;
--До PG10
select
client_addr as client, usename as user, application_name as name, state,
sync_state as mode,
(pg_xlog_location_diff(pg_current_xlog_location(),sent_location) /
1024)::int as pending,
(pg_xlog_location_diff(sent_location,write_location) / 1024)::int as write,
(pg_xlog_location_diff(write_location,flush_location) / 1024)::int as
flush,
(pg_xlog_location_diff(flush_location,replay_location) / 1024)::int as
replay,
(pg_xlog_location_diff(pg_current_xlog_location(),replay_location) /
1024)::int / 1024 as total_lag
from pg_stat_replication;

Теперь мождно глянуть на слейве наличие реплики:

postgres=# select * from pg_stat_wal_receiver \gx

ВУАЛЯ!

П.С. На текущий момент времени задача репликации выполнена. Следущий этап — создание синхронной репликации и подключение WAL-G для хранения архива WAL файлов в AWS S3.

П.П.С. Помните, что репликация — это не бекап данных!

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

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