(этап 5) Настройка репликации встроенными инструментами СУБД (ручной Failover/Switchover).

Выполняется на Master db1 10.2.0.11 :

Создадим отдельного пользователя для репликации repl - имя пользователя

sudo -iu postgres psql
CREATE ROLE repl WITH REPLICATION LOGIN ENCRYPTED PASSWORD '12345678';
\password  # сменим пароль на УЗ postgres внутри СУБД Tantor (пример пароль postgres)

Правим строчку в pg_hba, тут со стороны заказчика нужно указать, что куда добавить Правило подключения, если необходимо. Не всегда это нужно в рамках тестового пилота, Можно оставить так.

!!! чтобы не мучиться с корректировкой настроек после pg_rewind, для repl можно указать всю подсеть 10.2.0.0/24
sudo nano /var/lib/postgresql/tantor-be-16/data/pg_hba.conf
host    replication     repl         10.2.0.12/32            scram-sha-256
host    all             all          0.0.0.0/0               scram-sha-256

Добавляем параметры, ip адрес Master сервера в настройку инстанса

nano /var/lib/postgresql/tantor-be-16/data/postgresql.conf

или через psql, параметры запишутся в postgresql.auto.conf

sudo -iu postgres psql
alter system set listen_addresses = 'localhost, 10.2.0.11'; -- можно '*', чтобы не перенастраивать после pg_rewind
alter system set wal_level = replica;
alter system set wal_log_hints = on;
alter system set max_wal_senders = 10;
alter system set fsync = on;
alter system set synchronous_commit = on;
alter system set hot_standby = on;
alter system set hot_standby_feedback = on;
alter system set synchronous_standby_names = '1 (db1, db2)'; -- для async репликации оставьте пустое значение
alter system set max_replication_slots = 10;
alter system set wal_keep_size = '1GB';  -- или больше, в зависимости от требований

После внесение изменений перезапускаем сервис

sudo systemctl restart tantor-be-server-16.service
Выполняем на Replica сервере db2 10.2.0.12 :
systemctl stop tantor-be-server-16.service
su - postgres
cd /var/lib/postgresql/tantor-be-16/

Сохраним архивную копию папки data если потребуется для восстановления или удаляем

tar -cvzf main_backup-`date +%s`.tgz data
rm -rf data/

Переносим папку data c Master сервера на Реплику с созданием слота репликации -C -S db2_replica:

export PGAPPNAME=db2
pg_basebackup -h db1 -U repl -p 5432 -D data -R -X stream -C -S db2_replica -c fast -P
PASSWORD '12345678'

Проверяем, появилась ли data каталог

ls -la data/

Исправим на правильный listen_addresses Если указывали listen_addresses = '*', то не нужно

nano /var/lib/postgresql/tantor-be-16/data/postgresql.conf

или

nano /var/lib/postgresql/tantor-be-16/data/postgresql.auto.conf
listen_addresses = 'localhost, 10.2.0.12'

Корректируем правило в pg_hba.conf, для того чтобы после смены лидера, db1 смог подключаться к db2. Если указывали 10.2.0.0/24, то не нужно.

nano /var/lib/postgresql/tantor-be-16/data/pg_hba.conf
host    replication     repl         10.2.0.11/32            scram-sha-256

Запустим сервис

sudo systemctl start tantor-be-server-16.service
sudo systemctl status tantor-be-server-16.service

На мастере db1 10.2.0.11 проверить реплику

sudo -iu postgres psql -c "select client_addr, usename, application_name, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn from pg_stat_replication;"

На реплике db2 10.2.0.12 , вывод должен быть true

sudo -iu postgres psql -c "select status,sender_host,sender_port, slot_name from pg_stat_wal_receiver;
SELECT pg_is_in_recovery();"

Проверим репликацию, создадим сущность данных в СУБД на мастере db1 10.2.0.11

sudo -iu postgres psql -c "create database tesdb2;"

Проверим на реплике db2 10.2.0.12

sudo -iu postgres psql -c "\l"

Смена лидера. (меняем роли местами мастер -> реплику).

Проверить статус репликации на db2 10.2.0.12 Должно вернуть true (реплика в режиме восстановления)

sudo -iu postgres psql
SELECT pg_is_in_recovery();

Проверить отставание на db2 10.2.0.12

SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(), pg_last_xact_replay_timestamp();

смотрим статус синхронизации на мастере db1 10.2.0.11

sudo -iu postgres psql
\x
SELECT * FROM pg_stat_replication;
Перед переключением мастера на реплику, рекомендуется остановить режим записи СУБД на мастере db1, чтобы избежать потери данных.

Это можно сделать с помощью команды:

ALTER SYSTEM SET default_transaction_read_only = ON;
SELECT pg_reload_conf();

На реплике выполните db2 10.2.0.12 Относительно видео - скорректировано создание слота репликации db1_replica

SELECT pg_promote();
SELECT pg_is_in_recovery();   ## Должно быть `false` (теперь это мастер)
SELECT * FROM pg_create_physical_replication_slot('db1_replica'); ## создать слот репликации для новой реплики
SELECT slot_name, slot_type FROM pg_replication_slots;  ## проверим что новый слот создался

Остановить сервис tantor на мастере db1 10.2.0.11

sudo systemctl stop tantor-be-server-16.service

выполняем догон db1 10.2.0.11 , новой реплики относительно нового мастера.
Делаем pg_rewind под УЗ postgres, так как пользователь должен иметь права с доступом к функции pg_read_binary_file.
либо при создании УЗ repl дать привилегии, если планируете использовать ее для pg_rewind.
GRANT EXECUTE ON FUNCTION pg_read_binary_file(text, bigint, bigint, boolean) TO repl;
В PostgreSQL доступ к функции pg_read_binary_file ограничен по соображениям безопасности, так как она позволяет читать произвольные файлы на сервере. Обычно только суперпользователи (superuser) имеют к ней доступ.

su - postgres
pg_rewind --target-pgdata=/var/lib/postgresql/tantor-be-16/data --source-server="host=db2 port=5432 user=postgres dbname=postgres password=postgres" -P

Создайте файл standby.signal db1 10.2.0.11

touch /var/lib/postgresql/tantor-be-16/data/standby.signal
rm -f /var/lib/postgresql/tantor-be-16/data/postmaster.pid  ## на всякий случай

Настроить старый мастер db1 10.2.0.11 как новую реплику. Отредактируем строчки в файле
primary_slot_name = 'db1_replica'
host=db2 , application_name=db1

nano /var/lib/postgresql/tantor-be-16/data/postgresql.auto.conf
primary_conninfo = 'user=repl password=12345678 channel_binding=prefer host=db2 port=5432 application_name=db1 sslmode=prefer sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'db1_replica'

Корректируем правило в pg_hba.conf, для того чтобы после смены лидера, db2 смог подключаться к db1. Если указывали 10.2.0.0/24, то не нужно.

nano /var/lib/postgresql/tantor-be-16/data/pg_hba.conf
host    replication     repl         10.2.0.12/32            scram-sha-256

Запустить сервис tantor на db1 10.2.0.11

sudo systemctl start tantor-be-server-16.service

Проверим на новом мастере db2 10.2.0.12:

sudo -iu postgres psql -c "select client_addr, usename, application_name, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn from pg_stat_replication;"

На новой реплике db1 10.2.0.11:

sudo -iu postgres psql -c "select status,sender_host,sender_port, slot_name from pg_stat_wal_receiver;
SELECT pg_is_in_recovery();"

Если мы хотим полностью разделить БД и сделать самостоятельными: synchronous_commit = off делать ненужно, это отключает синхронную фиксацию записи данных транзакции на диск, нарушит надежность сохранности данных.

SELECT pg_promote();
alter system set synchronous_standby_names = '';
SELECT pg_reload_conf();
SELECT  pg_is_in_recovery();                      ## убедитесь, что сервер действительно стал основным, должно быть false
select pg_drop_replication_slot('db1_replica');   ## на db2