Repmgr: streaming replication, so easy, so simple.
Repmgr это инструмент с помощью которой можно сильно облегчить процесс развертывания и управления потоковой репликацией в PostgreSQL. Repmgr предназначен как для DBA, так и для системных администраторов которые работают с PostgreSQL. Repmgr позволяет выполнять следующие задачи:
- быстрое развертывание stand-by сервера;
- выполнение ручного switch-over на резервный stand-by сервер;
- переключение stand-by серверов на нового мастера в случае switch-over;
- мониторинг состояния потоковой репликации на stand-by узлах;
- предоставление единой точки управления кластером.
- установка repmgr на всех узлах с PostgreSQL;
- правка конфигурации PostgreSQL;
- создание SSH ключей, настройка авторизации, создание сервисной базы и пользователя;
- копирование базы и запуск реплики;
- настройка мониторинга;
- обработка аварийной ситуации.
# cave resolve repmgr -x
Для того чтобы начать использовать Repmgr, кластер потоковой репликации должен быть предварительно настроен. Если кластер не настроен, то можно сделать это сейчас. Даже если у вас всего один сервер, его также можно настроить на работу в режиме потоковой репликации (например с прицелом на будущее).
Для настройки потоковой репликации нужно изменить postgresql.conf на всех узлах кластера. Конфигурация должна быть одинаковой на всех узлах и содержать опции относящиеся как к мастеру так и к stand-by, это поможет избежать лишних перезапусков postgresql-сервера.
Отдельного внимания заслуживают опции архивирования и опция wal_keep_segments. Эти опции должны быть включены, это обязательное требование, в случае если опции отключены, repmgr откажется выполнять копирование.
Эти два условия гарантируют что резервная копия после копирования будет рабочей. Опция wal_keep_segments определяет количество сегментов WAL и гарантирует нам, что для WAL журналов не будет выполняться ротация во время копирования. Вместо ротации сегменты будут скапливаться пока не достигнут значения указанного в wal_keep_segments (после чего начнут удаляться). Если число сегментов WAL выйдет за значение wal_keep_segments, то самые старые WAL сегменты будут удалены, а копируемая копия станет попросту нерабочей. Избежать этого можно с помощью архивирования WAL. Архивирование гарантирует что WAL сегменты всегда будут архивированы.
В примере указанном ниже, архивирование включено в холостом режиме, ничего никуда копироваться не будет. Значение wal_keep_segments установлено в 1024, в большинстве случаев этого будет достаточно. При установке wal_keep_segments стоит помнить, что каждый сегмент занимает 16MB пространства, поэтому предварительно следует оценить сколько места будет занимать указываемое количество сегментов.
# vi /etc/postgresql-9.3/postgresql.conf
listen_addresses = '*'
wal_level = 'hot_standby'
archive_mode = on
archive_command = 'exit 0'
max_wal_senders = 3
wal_keep_segments = 1024
hot_standby = on
Также следует определить конфигурацию pg_hba для авторизации. В моем случае используется парольная MD5 авторизация. Нужно разрешить доступ к репликации для выделенного пользователя repmgr который будет создан чуть позже.
# vi /etc/postgresql-9.3/pg_hba.conf
host repmgr repmgr 172.17.99.0/24 md5
host replication repmgr 172.17.99.0/24 md5
После редактирования конфигурации, PostgreSQL следует перезапустить.
Все работы и операции связанные с Repmgr будут выполняться от имени системного пользователя postgres. Поэтому сейчас следует настроить возможность авторизации пользователя postgres между узлами кластера потоковой репликации. Для этого будем использовать ssh и публичные ключи. Это делается из-за того что копирование базы выполняется посредством rsync (копирование через pg_basebackup не реализовано).
Генерируем ключи и копируем их на все узлы кластера.
root@master # su - postgres
postgres@master $ mkdir ~/.ssh
postgres@master $ ssh-keygen -t rsa -b 2121
postgres@master $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
postgres@master $ rsync -av ~/.ssh/ root@slave1:~postgres/.ssh/
Теперь создаем отдельную роль и базу для нужд repmgr. Создаваемая база будет использоваться для хранения служебной схемы и таблиц repmgr. Реквизиты подключения прописываем в .pgpass пользователя postgres на всех узлах.
root@master # psql -U postgres -c "create role repmgr with login replication encrypted password 'repmgrpass'"
root@master # psql -U postgres -c "create database repmgr with owner repmgr"
root@slave1 # echo "*:*:*:repmgr:repmgrpass" > ~postgres/.pgpass
root@slave1 # chown postgres: ~postgres/.pgpass
root@slave1 # chmod 600 ~postgres/.pgpass
После создания ключей, нужно выполнить подключение по ssh с каждого stand-by узла на мастер, это необходимо для получения host-ключей сервера и их добавления в known_hosts. Затем следует проверить подключение к PostgreSQL серверу на мастере.
postgres@slave1 $ psql -h master -U repmgr repmgr
В случае успеха переходим к следующему этапу, в обратном случае возвращаемся назад и перепроверяем настройки pg_hba.
Запуск реплики.
В случае успеха, переходим к созданию реплики. При необходимости создаем каталог, определяем права и владельца. После чего становимся пользователем postgres и запускаем процесс клонирования. Обратите внимание на ключ -w, с помощью него указывается минимальное значение wal_keep_segments на случай если значение в postgresql.conf меньше чем требует repmgr.
root@slave1 # mkdir /data/pg/db
root@slave1 # chown postgres: /data/pg/db
root@slave1 # chmod go-rwx /data/pg/db
root@slave1 # su - postgres
postgres@slave1 $ repmgr -D /data/pg/db/ -U repmgr -d repmgr -w 100 --verbose standby clone 172.17.99.80
Процесс копирования занимает некоторое время которое зависит от размера базы. Учитывая некоторую специфику PostgreSQL после запуска копирования может сложиться впечатление что команда зависла и ничего не делает. Это не так, перед тем как начать копирование, PostgreSQL переходит в backup режим и это занимает определенное время (которое может быть разным и зависит от интенсивности изменений в базе и значений checkpoint_timeout и checkpoint_completion_target). После завершения копирования следует запустить postgresql и проверить успешность через журнал.
root@slave1 # rc-service postgresql-9.3 start
root@slave1 # tail -f /data/pg/db/postmaster.log
postgres[26792]: [5-1] LOG: entering standby mode
postgres[26793]: [3-1] LOG: started streaming WAL from primary at 3/B3000000 on timeline 1
postgres[26792]: [6-1] LOG: redo starts at 3/B3000028
postgres[26792]: [7-1] LOG: consistent recovery state reached at 3/B30000F0
postgres[26787]: [3-1] LOG: database system is ready to accept read only connections
Последняя строка свидетельствует о том что PostgreSQL запустился и готов обслуживать запросы клиентов.
Мониторинг.
А дальше мы можем настроить простейшее средство наблюдения за нашим кластером потоковой репликации. Для этого на каждом из узлов следует определить конфигурацию repmgr и зарегистрировать узел. Под регистрацией понимается добавление информации об узле в служебную базу repmgr. Вообще процесс регистрации обязателен если вы хотите в будущем выполнять преобразование stand-by в мастера или перенастройку stand-by на нового мастера.
root@master # vi /etc/repmgr.conf
cluster=staging
node=1
conninfo='host=172.17.99.80 dbname=repmgr user=repmgr'
root@slave1 # vi /etc/repmgr.conf
cluster=staging
node=2
conninfo='host=172.17.99.81 dbname=repmgr user=repmgr'
Регистрируем узлы и смотрим состояние кластера.
postgres@master $ repmgr -f /etc/repmgr.conf master register
Master node correctly registered for cluster sg with id 1 (conninfo: host=172.17.99.80 dbname=repmgr user=repmgr)
postgres@slave1 $ repmgr -f /etc/repmgr.conf standby register
postgres@slave1 $ repmgr -f /etc/repmgr.conf cluster show
Role | Connection String
* master | host=172.17.99.80 dbname=repmgr user=repmgr
standby | host=172.17.99.81 dbname=repmgr user=repmgr
Дополнительно на каждом из stand-by узлов можно запустить repmgrd. Это отдельный небольшой демон который подключен к мастеру и stand-by узлу и наблюдающий за состоянием репликации. Repmgrd для работы требует ранее настроенный /etc/repmgr.conf
root@slave1 # rc-service repmgrd start
Состояние репликации можно увидеть с помощью следующего запроса:
postgres@slave1 $ psql -U repmgr -x -c "select * from repmgr_sg.repl_status"
-[ RECORD 1 ]-------------+------------------------------
primary_node | 1
standby_node | 2
last_monitor_time | 2013-10-27 12:53:47.985443+06
last_wal_primary_location | 6/FD050C58
last_wal_standby_location | 6/FD050C58
replication_lag | 0 bytes
apply_lag | 0 bytes
time_lag | 00:00:00.065552
Обратите внимание на time_lag - это время на которое stand-by отстает от master сервера.
Обслуживание аварийных ситуаций.
Теперь предположим произошло страшное и мастер сервер стал недоступен. Теперь мы можем выполнить switch-over и провозгласить один из stand-by'ев в мастера. Если просмотреть состояние кластера, то можно увидеть что один из узлов находится в состоянии FAILED.
postgres@slave1 $ repmgr -f /etc/repmgr.conf cluster show
Role | Connection String
FAILED | host=172.17.99.80 dbname=repmgr user=repmgr
standby | host=172.17.99.81 dbname=repmgr user=repmgr
Запускаем процесс переконфигурации stand-by в master:
postgres@slave1 $ repmgr -f /etc/repmgr.conf standby promote
repmgr: STANDBY PROMOTE successful. You should REINDEX any hash indexes you have.
Тут следует отметить что для переконфигурации, repmgr выполняет перезапуск PostgreSQL, хотя опытные администраторы и DBA, знают что преобразование можно выполнить и без перезапуска. После переконфигурации проверяем кластер, узел стал отображаться в роли мастера.
postgres@slave1 $ repmgr -f /etc/repmgr.conf cluster show
Role | Connection String
FAILED | host=172.17.99.80 dbname=repmgr user=repmgr
* master | host=172.17.99.81 dbname=repmgr user=repmgr
При наличии нескольких stand-by оставшиеся узлы можно переподключить к новому мастеру с помощью следующей команды:
postgres@slave2 $ repmgr -f /etc/repmgr.conf standby follow
И в качестве небольшого бонуса. Для удаления FAILED узлов из вывода cluster show следует поправить записи в таблице repl_nodes в базе repmgr. Наш сбойный узел числился с id = 1, значит удаляем его, а новый мастер ставим на его место.
repmgr=# delete from repmgr_staging.repl_nodes where id = 1;
repmgr=# update repmgr_staging.repl_nodes set id = 1 where id = 2;
Вот так вот, как видно Repmgr может довольно хорошо облегчить работу администратора связанную с обслуживанием потоковой репликации.
На главную "Virtualizing Linux"
Комментариев нет:
Отправить комментарий