Отказоустойчивый PostgreSQL кластер. Часть 5. Тестирование. Ansible. Вместо послесловия.


Часть 1. Введение.
Часть 2. Репликация. Repmgr.
Часть 3. Auto-failover. Демоны repmgr.
Часть 4. Высокая доступность. Бэкапирование. Демоны repmgr. Barman.
Часть 5. Тестирование. Ansible. Вместо послесловия.

Ручное переключение серверов

На сервере backup запустите.

su - postgres
repmgr standby switchover -f /etc/repmgrd_db2.conf --log-to-file

Автоматическое переключение серверов

db2 теперь новый мастер. Погасите db2.

shutdown -h now

Подождите пока db1 не станет новым мастером. Запускайте на сервере backup:

tail -50 /var/log/syslog | grep repmgr
repmgrd[6872]: unable to ping "host=10.8.2.1 user=repmgr dbname=repmgr connect_timeout=2"
repmgrd[6872]: unable to connect to upstream node "db2" (node ID: 2)
repmgrd[6872]: checking state of node 2, 1 of 6 attempts
repmgrd[6872]: unable to ping "user=repmgr connect_timeout=2 dbname=repmgr host=10.8.2.1 fallback_application_name=repmgr"
repmgrd[6872]: sleeping 10 seconds until next reconnection attempt
repmgrd[6872]: checking state of node 2, 2 of 6 attempts
repmgrd[6872]: unable to ping "user=repmgr connect_timeout=2 dbname=repmgr host=10.8.2.1 fallback_application_name=repmgr"
repmgrd[6872]: sleeping 10 seconds until next reconnection attempt
repmgrd[6872]: checking state of node 2, 3 of 6 attempts
repmgrd[6872]: unable to ping "user=repmgr connect_timeout=2 dbname=repmgr host=10.8.2.1 fallback_application_name=repmgr"
repmgrd[6872]: sleeping 10 seconds until next reconnection attempt
repmgrd[6872]: checking state of node 2, 4 of 6 attempts
repmgrd[6872]: unable to ping "user=repmgr connect_timeout=2 dbname=repmgr host=10.8.2.1 fallback_application_name=repmgr"
repmgrd[6872]: sleeping 10 seconds until next reconnection attempt
repmgrd[6872]: checking state of node 2, 5 of 6 attempts
repmgrd[6872]: unable to ping "user=repmgr connect_timeout=2 dbname=repmgr host=10.8.2.1 fallback_application_name=repmgr"
repmgrd[6872]: sleeping 10 seconds until next reconnection attempt
repmgrd[6872]: checking state of node 2, 6 of 6 attempts
repmgrd[6872]: unable to ping "user=repmgr connect_timeout=2 dbname=repmgr host=10.8.2.1 fallback_application_name=repmgr"
repmgrd[6872]: unable to reconnect to node 2 after 6 attempts
repmgrd[6872]: primary and this node have the same location ("default")
repmgrd[6872]: no other sibling nodes - we win by default
repmgrd[6872]: this node is the only available candidate and will now promote itself
repmgrd[6872]: promote_command is:#012  "ssh postgres@10.8.1.1 /usr/bin/repmgr standby promote -f /etc/repmgr.conf --log-to-file"
repmgrd[6872]: executing notification command for event "repmgrd_failover_promote"
repmgrd[6872]: 0 followers to notify
repmgrd[6872]: switching to primary monitoring mode
repmgrd[6872]: executing notification command for event "repmgrd_reload"
repmgrd[6872]: monitoring cluster primary "db1" (node ID: 1)

Проверьте кластер.

su - postgres
repmgr -f /etc/repmgrd_db1.conf cluster show

Возврат экс-мастера назад в кластер

db1 снова мастер. Вернем db2 назад в кластер.

Для начала, запустите db2.
Затем, запустите OpenVPN.

systemctl start openvpn

Потом, запустите rejoin на сервере db2.

su - postgres
repmgr -f /etc/repmgr.conf node rejoin -d "postgres://repmgr@10.8.1.1:5432/repmgr" --force-rewind

Repmgr будет использовать pg_rewind, так что возврат сервера в строй должен быть быстрее, чем при полном бэкапировании.

ВАЖНО. Убедитесь, что демоны repmgr переподключились к свежевозвращенному среверу каждый раз когда хотите опять деградировать кластер.

tail -50 /var/log/syslog | grep repmgr
repmgrd[10061]: monitoring primary node "db2" (node ID: 2) in normal state
repmgrd[10061]: attempting to reconnect to node "db2" (ID: 2)
repmgrd[10061]: reconnected to node "db2" (ID: 2)
repmgrd[10061]: node is now a standby, switching to standby monitoring
repmgrd[10061]: executing notification command for event "repmgrd_standby_reconnect"

Возврат поврежденного экс-мастера назад в кластер

ОК, давайте представим, что файлы базы данных на сервере db2 повреждены, но ОС продолжает работать. Процесс восстановления в таком случае очень похож на процесс создания резервного сервера.
Запустите OpenVPN.

systemctl start openvpn

Запустите клонирование и перерегистрацию резервного сервера.

su - postgres
rm -r /var/lib/postgresql/11/main/* #not remove, but move if you need to
repmgr -h 10.8.1.1 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone -F
chmod 700 /var/lib/postgresql/11/main/
sudo pg_ctlcluster 11 main start
repmgr standby register --force

Если repmgr сконфигурирован на использование barman, файлы бэкапа будут взяты с сервера barman и процесс восстановления не потревожит мастер-сервер.

Проверяем бэкап

Сымитируйте нагрузку на БД. Зайдите в базу как repmgr на сервере backup.

su - postgres
psql -U repmgr -d repmgr -h 10.8.3.1 -p 54322

Создайте тестовую таблицу и запустите тестовый скрипт.

create table t(n integer);

DO
$$
begin 
	for i in 1..100000 loop 
		insert into t values(i); 
		RAISE NOTICE 'Val: %',i; 
		commit; 
	end loop; 
end;
$$;

Сразу после этого, жестко перезагрузите сервер db1.

Подождите пока сервер db2 не станет мастером, как было показано выше.

Зайдите на новый мастер(db2) и вставьте еще строчку данных.

psql -U repmgr -d repmgr -h 10.8.3.1 -p 54322
insert into t values (0);

Остановите тестовый экземпляр БД на сервере backup перед разворотом бэкапа.

systemctl stop postgresql

Подготовьте директорию PostgreSQL для barman.

rm -r /var/lib/postgresql/11/main/*
chown barman:barman /var/lib/postgresql/11/main/

Восстановите последний возможный бэкап. Barman пока что не поддерживает ключевое слово latest в качестве target-time, поэтому просто укажите дату где-нибудь в будущем, мы переопределим её вскоре.

barman recover main_backup --target-time="2030-01-01 00:00:00" latest /var/lib/postgresql/11/main/

Скопируйте последний имеющийся partial WAL и переименуйте его.

cp /var/lib/barman/main_backup/streaming/*.partial /var/lib/postgresql/11/main/pg_wal/
rename 's/.partial//' /var/lib/postgresql/11/main/pg_wal/*

Переопределите точку восстановления, автоматически заданную barman.

echo "recovery_target_timeline = 'latest'" >> /var/lib/postgresql/11/main/recovery.conf

Верните права назад юзеру postgres и запустите экземпляр.

chown -R postgres:postgres /var/lib/postgresql/11/main/
systemctl start postgresql

Успешный старт базы командой не означает, что она уже восстановлена на последнюю точку. Проверяйте логи, пока база не будет готова принимать rw-соединения.

tail -50 /var/log/postgresql/postgresql-11-main.log
...
[31625] LOG:  restored log file "0000000D000000000000002B" from archive
[31625] LOG:  restored log file "0000000E000000000000002C" from archive
...
[31624] LOG:  database system is ready to accept connections

Зайдите в psql и проверьте что все строки на месте.

su - postgres
psql -U repmgr -d repmgr -h 127.0.0.1
select count(*) from t;

I want to ride my Ansible! Ansible!


ЗДЕСЬ

Вместо послесловия

Так, и что мне дальше делать?

  • Установите HAproxy, чтобы иметь отдельный порт для ro-соединений. Перенаправьте ro-запросы к резервному серверу с автопереключением на мастер, если резервный недоступен. Вы можете использовать external check script и селект к repmgr через порт 54322 чтобы определить роль сервера.
  • Запустите pgbouncer через порт 54322
  • Подумайте дважды о безопасности сервера backup. Это наиболее уязвимый сервер кластера, потому что на нем располагаются все бэкапы и он может подключаться к серверам БД без пароля по ssh.
  • Подумайте дважды о безопасности серверов db1 и db2. Если вы используете barman как метод восстановления в repmgr, серверы БД могут подключаться к backup без пароля по ssh.
  • Установите систему мониторинга, которая будет мониторить демонов repmgr, barman и состояние кластера после автоматического переключения.
  • Поблагодарите меня. Это было нелегко.

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

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