Благодарность
Спасибо тебе, Хабр, за то, что ты есть и за те прекрасные часы которые я проводил в тебе! Спасибо, отважные хаброписатели, за статьи высокого качества, тонкого юмора и широкого кругозора. Только благодаря вам и Марь Ивановне (которая меня в первом классе научила читать) я добился серьёзных успехов в ИТ, а теперь хочу поделиться историей, когда нестандартное
Вступление
Некоторое время назад я работал над проприетарным продуктом. Этот софт хранил свои данные во внешней СУБД. Первоначально работа осуществлялась с MS SQL, однако позже специально для пользователей «я только *nix-подобные системы ставлю» сделали совместимость с PostgreSQL. Тут взяли меня для решения задач класса «база данных упала — нужно восстановить по журналам транзакций».
В один прекрасный день команда поехала реализовывать очередной проект. Первоначально было оговорено, что на объекте уже есть два сервера Windows 2012, на которых будет развёрнут отказоустойчивый кластер MS SQL. Однако в последний момент у заказчика денег на инстансы не хватило, и мне было поручено ставить рostrge'совые БД, а так же как-то решить задачу отказоустойчивости. Спасибо сообществу разработчиков рostgres, которые скомпилировали установщик для Windows. Задачи:
- Установить СУБД PostgreSQL на Windows;
- Обеспечить репликацию данных между БД;
- Решить вопрос с отказоустойчивостью.
1. Установка PostgreSQL
Здесь всё просто:
- Качаем дистрибутив для Windows — нам подойдёт версия 9.4 для х64;
- Запускаем установщик, выбираем русскую локаль, установку в директорию по умолчанию и играем в эникейщика, нажимая кнопку «Далее».
Примечание: Stack bilder в конце можно не запускать — его элементы нам не потребуются.
2. Репликация данных
По умолчанию нам поставиться Slony-I, однако асинхронная репликация уже есть в «коробке», чем мы и воспользуемся. Иногда доступ к командной строке linux и файлам настройки ИБшники отказывались выдавать, и мне приходилось настраивать СУБД через psql, поэтому далее пойдут mad skillz. Здесь и в последующем все утилиты берутся из папки C:Program FilesPostgreSQL9.4bin (правильно было бы указать переменную $PGDATA, но она почему-то по умолчанию не была задана инсталлятором). На мастере:
Подключаемся к СУБД командой:
psql.exe -U postgres
Включаем режим дублирования данных:
alter system set wal_level=hot_standby;
Отключаем режим архивирования:
alter system set archive_mode=off;
Разрешаем создавать слоты репликации:
alter system set max_replication_slots=1;
Задаём максимальное количество процессов репликации данных (второй процесс будет обслуживать работу утилиты pgadmin):
alter system set max_wal_senders=2;
Выполняем команду "\!" и… Ха-ха! Мы оказываемся в командной строке Windows. Редактируем файл pg_hba.conf (здесь и далее имеются ввиду файлы из папки C:Program FilesPostgreSQL9.4data). Он отвечает за доступ хостовпользователей к СУБД. Добавляем строчки:
# В дальнейшем этот файл перекачует на слейв
host all all <ip-мастера> md5
# Разрешаем всем пользователям с указанного хоста подключаться к любым БД
host all all <ip-slave> md5
host replication postgres <ip-мастера> trust
# Разрешаем пользователю postgres делать репликацию с указанного хоста без пароля
host replication postgres <ip-slave> trust</i><br>
На слейве:
1. Останавливаем службу postgresql.
2. Удаляем содержимое папки C:Program FilesPostgreSQL9.4data
3. Делаем бэкап с мастера при помощи команды pg_basebackup. В качестве параметров используем:
pg_basebackup -h <ip-мастера> -D "C:Program FilesPostgreSQL9.4data" -U postgres
В конце выполнения утилита возмутиться, что WAL-архивирование не настроено, но нам это принципиально не нужно из-за следующего этапа (как бонус — экономия дискового пространства).
4. Заходим в файл postgresql.auto.conf и устанавливаем параметры:
# Устанавливаем флаг "горячей замены"
hot_standby=on
# Включаем отлуп от слейва
hot_standby_feedback=on
# Отключаем интервал ожидания WAL-архива
wal_receiver_status_interval=0
Возвращаемся на мастер:
1. Назначаем хост мастером:
alter system set hot_standby=off;
2. Отключаем ожидание отклика от слейва:
alter system set hot_standby_feedback=off;
3. Отключаем интервал в передаче WAL-журнала:
alter system set wal_receiver_status_interval=0;
4. Перезапускаем службу СУБД на мастере (можно не выходя из psql):
\! pg_ctl restart -D "C:Program FilesPostgreSQL9.4data"
5. Создаём слот репликации:
select pg_create_physical_replication_slot('slot_1');
3. Отказоустойчивость
Slony-I не входил в спецификацию проекта, и к нему было лениво выдумывать скрипты PowerShell. Заказчик напрочь отказался ставить дополнительный linux-сервер, таким образом вариант с pgpool-II или pgbouncer отпал (да и непонятно, как ими работать с Windows). Поэтому остался переход в режим записи по файлу-триггеру. Донастроим слейв для перехода в режим мастера. Для этого необходимо создать файл recovery.conf и в него добавить строки:
standby_mode=on # Активируем режим ожидания
primary_conninfo='host=<ip_мастера> port=5432 user=postgres' # Настройки подключения к мастеру
primary_slot_name=slot_1 # Имя слота на мастере
trigger_file=startmaster # Имя файла, создание которого приведёт к запуску слева в режим записи
Примечание: если слейв перейдёт в режим мастера то файл поменяет имя на recovery.done.
Запускаем службу postgres на слейве. В случае успешной настройки она стартанёт корректно и будет стягивать данные с мастера. Проверить репликацию можно:
— На мастере при помощи команды:
select (active) from pg_replication_slots;
— На слейве можно попробовать создать какой-либо объект и получить ошибку транзакции «только на чтение». Для клиента можно на мастере создать тестовую таблицу, которая автоматически дублируется на слейве.
В случае сбоя мастера потенциальный сисадмин должен выполнить следующую последовательность действий:
а) Убедиться, что мастер на запись недоступен;
б) Проверить, что ip-адрес кластера СУБД свободен. Например, пингануть ip или вырубить сетевой интерфейс мастера;
в) Поменять ip слейва на ведущий;
г) Указать слейву работать как мастер. Для этого можно использовать pg_ctl promote (на объекте вываливалась ошибка повышений привилегий службы) или, так как мы настроили файл-триггер реконфигурации, создать пустой файл startmaster.
Дополнительно (то, что не входило в рамки поставленной задачи): из упавшего мастера можно сделать слейв, выполнив пункты настройки слейва из второго этапа.
Мой начальник пошутил: "Ты ж Шарп знаешь — напиши!". Два дня потуг в поле на коленке — я взял и запилил. Про основы ООП и потокобезопасность прошу все комментарии писать сюда).
Программа использует библиотеку Npgsql для работы с СУБД. Распаковать архив нужно на слейве и запустить программу на выполнение.
Далее требуется ввести:
— ip слейва;
— ip мастера;
— ip кластера (основной ip по идее должен совпадать с ip-мастера, но всякое бывает);
— имя БД, к которой будет производиться подключение (в ней создаться тестовая таблица testofcluster)
Для выполнения проверки кластера нужно нажав кнопку «Test». Программа проверит, что запущена на слейве, мастер позволяет производить запись в тестовую таблицу и репликация происходит в штатном режиме. В качестве бонуса будут сохранены файлы recovery.conf, postgresql.conf, postgresql.auto.conf на слейве, что упростит процедуру перевода мастера в режим слейва.
Запустить мониторинг: ПО циклически проверяет доступность мастера и в случае выхода его из строя — переводит слев в режим записи и меняет ip слева на кластерный.
Спецификация:
— Должен быть установлен dotnet 4.5
— Совместимость проверена на Windows 7 x64, Windows 2012 с PostgreSQL 9.4 (x64).
— Время реакции на выключение мастера — от 20 до 35 секунд (производиться поэтапная проверка доступности мастера и основного ip).
— Время перевода слева в мастер — менее 5 секунд (рестарт службы не требуется).
— Примечание: на виртуальных машинах (на VMware Workstation — 100%) не меняется ip-адрес.
— Windows должна быть русифицированная; в PostgreSQL должна быть выбрана русская локаль.
Загрузка: скачать архив со скомпилированной программой и двумя библиотеками можно отсюда.
Автор: postgrez4ik