вторник, мая 21, 2019

Жаркий день в аду

ИЛИ

Самый прикольный на этот день проект в моей жизни - система управления производством и заказами - состоит из пяти серверов в двух городах и проектировалась децентрализованной: серверы могут общаться, но отключение связи в любой точке не останавливает её работы: часть функций отпадает, основные действуют.

В каждом сервере торчит флешка, на которую еженощно бэкапится база данных.

Был один зияющий пробел, который меня беспокоил: однажды в одной из точек вылетит сервер. Это неизбежно случится. Что я буду делать?



К счастью, один из серверов чудовищно избыточен (настоящий, стоечный) и наименее загружен. Что если заготовить там работоспособные копии всех остальных систем и держать актуальные копии баз?

automysqlbackup создаёт бэкап базы в каталоге latest (при включенной опции latest), это хардлинк на последний файл в каталоге daily. Файл содержит в имени дату. Это неудобно, его надо переименовать (это значит, что файловая система должна поддерживать хардлинки, поэтому бэкапные флешки отформатированы в ext4).

Алгоритм:

1) монтируем флешку (на случай, если не);

2) бэкапим базу;

3) если удачно, удаляем daily.sql.qz в latest

4) переименовываем дамп базы в daily.sql.qz (в старых версиях дамп начинается с имени базы, в новых - с daily; соответственно, переименовываем файл, начинающийся на p или на d);

5) чмодим daily.sql.qz для чтения всеми (новая версия automysqlbackup создаёт его rw----).

Для этого создаём /root/backup с содержимым:

#!/bin/bash
mount /dev/sdb1 /mnt/backupflash; /usr/sbin/automysqlbackup && rm /mnt/backupflash/sql/latest/daily.sql.qz; mv $(ls /mnt/backupflash/sql/latest/p*) /mnt/backupflash/sql/latest/daily.sql.qz && chmod a+r /mnt/backupflash/sql/latest/daily.sql.qz

Выделено жирным: 1) automysqlbackup старых версий находится в /usr/local/bin, новых - в /usr/sbin; сделать whereis automysqlbackup от рута, чтобы узнать. 2) см. разницу p/d выше.

Делаем исполняемым chmod +x /root/backup и ставим в крон рута на ночное время.

0 3 * * * /root/backup >/dev/null 2>&1

Теперь на принимающей стороне. Здесь мы обходимся rsync в crontab:

0 7 * * * sshpass -p "PASSWORD" rsync LOGIN@HOST:/mnt/backupflash/sql/latest/daily.sql.gz /SOMEWHERE/HOST/ >/dev/null 2>&1

Чтобы это работало, надо предварительно соединиться по ssh с источником, чтобы сохранился ключ соединения. rsync должен иметься на обеих сторонах, конечно.

И копия рабочей системы:

5 7 * * * sshpass -p "PASSWORD" rsync -az LOGIN@HOST:/SOMEPATH /var/www/HOST >/dev/null 2>&1 

И резервные базы-то обновить, опустим подробности, это zcat и mysqladmin нужных файлов в нужные базы (их надо сперва создать).

Базы должны иметь различные между собой названия и такие же реквизиты доступа, как на оригинальных системах.

Дальше нам надо создать виртуальные серверы для каждой системы, я их делал на основе ip-адреса.

Я более-менее закончил с этим в понедельник вечером (нет предела совершенству: в идеале переключение между основной и резервной системой должно делаться в настройках центрального сервера - не успел).

Во вторник с утра вылетает один из серверов во Владивостоке.

Сука, едва успел пригнуться, а то бы убило.

Точка весь день работала на созданной накануне резервной системе. Если бы резерва не было, денежные потери потребовали бы для записи MEDIUMINT.

Поиск по этому блогу