Настройка потоковой репликации Postgresql сервера (WAL-репликация)


Главным недостатком потоковой репликации является, то что вы вынуждены реплицировать полностью сервер и не можете реплицировать отдельные таблицы и базы данных, вторым недостатком является, то что мастер и слэйв должны мало того, что одной версии, так и использовать одинаковую архитектуру (i386/x64/ARM) и теперь если вас все из вышеперечиcленного устраивает, то мы приступаем к настройке потоковой репликации.

Настраиваем MASTER-сервер

На основном сервере вносим изменения в конфигурацию (файл /etc/postgresql/10/main/pg_hba.conf):

host    replication     replicator       94.177.204.179/32       md5

мы сейчас разрешили доступ к нашему центральному серверу с адреса 94.177.204.179 (это наш Slave-сервер).

В основном конфигурационном файле (/etc/postgresql/10/main/postgresql.conf):

listen_addresses = '*'
hot_standby = on
wal_level = replica
wal_log_hints = on
max_wal_senders = 4
wal_keep_segments = 64
archive_mode = on
archive_command = 'cp -i %p /var/lib/postgresql/10/archive/%f'

В первом приближении этого достаточно чтобы сервер Postgresql начал выступать в качестве мастер-сервера. Самый главный из перечисленных параметров, это wal_level = replica и до Postgresql версии 10 он устанавливался в значение hot_standby:

Параметр wal_level определяет, как много информации записывается в WAL. Со значением replica (по умолчанию) в журнал записываются данные, необходимые для поддержки архивирования WAL и репликации, включая запросы только на чтение на ведомом сервере. Вариант minimal оставляет только информацию, необходимую для восстановления после сбоя или аварийного отключения. Наконец, logical добавляет информацию, требующуюся для поддержки логического декодирования. Каждый последующий уровень включает информацию, записываемую на всех уровнях ниже. Задать этот параметр можно только при запуске сервера.

Более подробно можно почитать тут: https://postgrespro.ru/docs/postgrespro/10/runtime-config-wal#RUNTIME-CONFIG-WAL-SETTINGS

Создаем каталог для хранения архива и назначаем права доступа к каталогу:

# mkdir /var/lib/postgresql/10/archive
# chown postgres:postgres /var/lib/postgresql/10/archive

Как вы видели в начале статьи, я разрешил доступ к серверу (для репликации) с одного IP-адреса и строго определенному пользователю которого сейчас необходимо создать и назначить ему привилегии и пароль:

# su postgres
$ psql
# CREATE USER replicator REPLICATION LOGIN CONNECTION LIMIT 2 ENCRYPTED PASSWORD 'XXXReplicXXX';
# /q

Для применения нового режима работы сервер баз данных придется перезагрузить:

# /etc/init.d/postgresql restart

Настраиваем SLAVE-сервер

На Slave-сервере необходимо остановить сервер баз данных командой:

# service postgresql stop

Следующим этапом вам требуется удалить текущие данные и скопировать базу с мастера командой pg_basebackup:

# rm -R /var/lib/postgresql/10/main/
# su postgres
$ pg_basebackup -P -R -X stream -c fast -h 80.211.102.101 -U replicator -D /var/lib/postgresql/10/main/
$ exit

После того как вы получили сообщение, что данные успешно скопированы необходимо внести правки в конфигурацию как в случае с MASTER-сервером (в файле /etc/postgresql/10/main/postgresql.conf):

hot_standby = on

Мы изменяем только один параметр и переключаем сервер в режим горячей замены. Теперь сервер будет получать данные с мастера, но при этом перейдет в режим Read Only.

Следующим этапом создаем файл /var/lib/postgresql/10/main/recovery.conf следующего содержания:

standby_mode = 'on' 
primary_conninfo = 'user=replicator password=XXXReplXXX host=80.211.102.101 port=5432'
restore_command = 'cp /var/lib/postgresql/10/archive/%f "%p"'

Кстати сказать если вы использовали pg_basebackup, то этот файл будет создан автоматически. Дополнительно можно создать запись:

trigger_file = '/tmp/postgresql-trigger'

Если вы создадите файл /tmp/postgresql-trigger с любым содержанием, то SLAVE автоматически переконфигурируется в MASTER.

Обратите внимание, на параметр restore-command он обратный к archive_command на MASTER сервере и каталог с архивами должен быть смонтирован на SLAVE с MASTER-сервера.

Мы все настройки произвели и можем запускать Postgresql-сервер:

# /etc/init.d/postgresql start

В списке системных процессов должен появиться процесс:

postgres: 10/main: wal receiver process  streaming 0/C0002C8

А в логах соответственно записи:

2018-08-01 13:45:40.009 +07 [14971] СООБЩЕНИЕ: для приёма подключений открыт Unix-сокет "/var/run/postgresql/.s.PGSQL.5432" 
2018-08-01 13:45:40.043 +07 [14972] СООБЩЕНИЕ: работа системы БД была прервана; последний момент работы: 2018-08-01 13:16:09 +07 
2018-08-01 13:45:40.070 +07 [14972] СООБЩЕНИЕ: переход в режим резервного сервера 
2018-08-01 13:45:40.074 +07 [14972] СООБЩЕНИЕ: запись REDO начинается со смещения 0/B000028 
2018-08-01 13:45:40.089 +07 [14972] СООБЩЕНИЕ: согласованное состояние восстановления достигнуто по смещению 0/B0000F8 
2018-08-01 13:45:40.090 +07 [14971] СООБЩЕНИЕ: система БД готова к подключениям в режиме "только чтение" 
2018-08-01 13:45:40.112 +07 [14976] СООБЩЕНИЕ: начало передачи журнала с главного сервера, с позиции 0/C000000 на линии времени 1

Теперь можете попробовать создать запись в таблице на мастер-сервере и проверить была ли она получена на SLAVE.

Диагностика репликации

В Postgresql 10 вы можете использовать следующий запрос для получения сведений о клиентах потоковой репликации:

# SELECT *,pg_wal_lsn_diff(s.sent_lsn,s.replay_lsn) AS byte_lag FROM pg_stat_replication s;