Система бэкапов mysql moodle на двух машинах через scp ssh

После вчерашнего танца с бубнами… Гм. Лучше по порядку. Вчера вышел из строя основной сервер. Я запустил резервный сервер, перекинул коммутацию интернетов в обход сервера. Этим я обеспечил интернеты. Потом поднял из бэкапов мудл, который у нас основным рабочим продуктом.

В более-менее спокойной обстановке народ разобрался с основным сервером (повезло — там была мелочь) и буквально через полчаса мы включили все обратно по основной схеме.

Все хорошо. Но. Я понял, что на сервере до сих пор крутится наколенная система бэкапов, которую я запустил полтора года назад. Да, я не сисадмин и вообще это не мой фронт работ, но если не я то, кто — и дальше следуют стандартные оправдания и дисклэймеры.

Из всего, что необходимо для работы мудла самую большую ценность представляет его база данных. Все прочее развертывается и ставится по отработанной схеме. А вот в MySQL хранятся все результаты, опросы и так далее. Поэтому основной задачей было обеспечить бэкап базы данных. Moodle используется как система опроса и контроля — причем не только нашей кафедрой, но и всем университетом — именно наша многострадальная машина. Что было до мудла — отдельная печальная и тоскливая песня про самописный софт. Посему обеспечение устойчивости мудл и его баз данных — задача номер раз.

То, что я сделал полтора (или два? не помню) года назад выглядело так:

#!/bin/bash
mysqldump -u root -pMySuperStrongBlahBlahBlahPassword moodle > moodle_`date +%F_%H_%M_%N`.sql

Собственно скрипт запускал mysqldump и под рутом (пользователь root пароль MySuperStrongBlahBlahBlahPassword) выгребал из MySQL базу данных (название moodle) и складировал ее в файл с текущей датой.

Плюс стандартный запуск в кроне (каждый день в 1000 запустить скрипт бэкапа):

main@main:/var/www/moodle$ crontab -l

    0 10 * * * /home/main/moodle_backup.sh

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

Сегодняшней задачей «по горячим следам» я поставил себе такую: сделать автоматический бэкап с main на sper, причем желательно так, чтобы можно было просто сказать местным пользователям — сегодня вместо http://172.20.0.13/moodle мы вводим http://172.20.0.7/moodle и дальше просто работать.

Как я к этому подошел? В моем распоряжении два сервера — main 172.20.0.13 и sper 172.20.0.7 Почему sper? Потому, что я спер этот топоним у ЦАХАЛа :) Мудл установлен и сконфигурирован на обоих машинах. Админ пароль на mysql — MySuperStrongBlahBlahBlahPassword

  • Поскольку я собирался задействовать scp — соеднил сервера по ssh.

Сгенерил ключи — без пассфразы.

ssh-keygen -t rsa

На вопрос о пароле надо нажать энтер — чтобы оно не интересовалось кодовой фразой каждый раз.

  • На main

Добавил в ~/.ssh/config:

Host sper 
    HostName 172.20.0.7
    User main
    IdentityFile ~/.ssh/id_rsa
  • На sper

Добавил в ~/.ssh/config:

Host main 
    HostName 172.20.0.13
    User main
    IdentityFile ~/.ssh/id_rsa

Это обеспечивает независимость скриптов от ip — в случае чего надо будет просто подправить конфиг ssh.

Прокинул ssh-copy-id с main на sper

ssh-copy-id -i id_rsa.pub main@sper
  • Подправил конфиг мудла на sper.

Раньше sper был 172.20.0.5. Теперь 172.20.0.7 Кроме того, я хотел знать, какую именно базу данных он использует. Оказалось ничего особо менять не надо — подправил 5 на 7 — все заработало на ура.

main@sper:/var/www/moodle$ sudo cat config.php
[sudo] password for main: 

<?php  /// Moodle Configuration File 

unset($CFG);

$CFG = new stdClass();
$CFG->dbtype    = 'mysql';
$CFG->dbhost    = 'localhost';
$CFG->dbname    = 'moodle';
$CFG->dbuser    = 'moodleuser';
$CFG->dbpass    = 'blablablapassword';
$CFG->dbpersist =  false;
$CFG->prefix    = 'mdl_';
...

$CFG->wwwroot   = 'http://172.20.0.7/moodle';
...

main@main:/var/www/moodle$
  • Написал два скрипта.

На main подредактировал старый скрипт:

#!/bin/bash

# задаемся именами основного файла и архива

name="moodle_`date +%F_%H_%M_%N`.sql"
tar_name=$name".tar.bz2"

# тестовая строка 

# echo $name
# echo $tar_name

# дампируем базу данных 
mysqldump -u root -pMySuperStrongBlahBlahBlahPassword moodle > $name

# сжимаем базу данных 
tar -jvcf $tar_name $name

# перекладываем ее в папку с бэкапами 
mv $tar_name ~/backup_moodle/

# mysqldump -u root -pMySuperStrongBlahBlahBlahPassword moodle > moodle_`date +%F_%H_%M_%N`.sql

# копируем ее на sper 
scp ~/backup_moodle/$tar_name sper:~/moodle_backup

Поскольку он у меня и так забит в cron — так его там и оставил.

main@main:/var/www/moodle$ crontab -l

    0 10 * * * /home/main/moodle_backup.sh

На sper создал moodle_restore.sh который распаковывает последнюю по времени базу данных и восстанавливает ее для локального мудла.

#!/bin/bash

# получаем имена основного файла и архива
# просто по дате изменения файлов
tar_name=`ls -1tr | grep ^moodle_2 | tail -n1`
name=`ls -1tr | grep ^moodle_2 | tail -n1 | sed 's/\(.*\).tar.bz2$/\1/'`

echo $name
echo $tar_name

# копируем в /tmp и уходим туда 
cp /home/main/moodle_backup/$tar_name /tmp
cd /tmp

# распаковываем архив 
tar -jxvf /tmp/$tar_name

# удаляем базу данных 
mysqladmin -f -u root -pMySuperStrongBlahBlahBlahPassword drop moodle                                                             

# создаем ее по новой 
mysql -u root -pMySuperStrongBlahBlahBlahPassword  -e "create database moodle"

# выливаем туда бэкап 
mysql -u root -pMySuperStrongBlahBlahBlahPassword moodle < /tmp/$name 

# !!!!!!! при задейстовании бэкапа в качестве основной машины нужно отключить бэкап по крону!

Здесь скрипт специально запускается с запозданием — в 1130. Обе машины включаются и выключаются ежедневно персоналом (не смог добиться того, чтобы все работало круглосуточно по административным причинам). Поэтому первый скрипт срабатывает в 1000, второй — в 1130

main@sper:/var/www/moodle$ crontab -l

    30 11 * * * /home/main/moodle_backup/moodle_resore.sh

Дополнительно я установил на обе машины ntp (почему-то не озаботился при начальной инсталляции системы) — чтобы не было проблем со временем.

Итого. В 1000 на основной машине запускается бэкапер, который (а) выливает базу данных из мудла, (б) запаковывает его в архив, (в) копирует архив по scp на запасную машину. В 1130 на запасной машине запускается ресторер, который (а) распаковывает последний по времени архив, (б) удаляет из MySQL старую базу данных, (в) заменяет ее новой базой данных.

Таким образом имеем на запасной машине полную, готовую к работе копию мудла не больше чем однодневной давности.

По уму следовало бы:

— сделать слив и залив бэкапов не по рутовому логину для MySQL, а по специальному пользовательскому
— проверять в сети ли машины или нет и произошло ли копирование или нет
— дополнительно сливать бэкапы на резервные машины (например на мой рабочий десктоп)
— подправить регулярки, чтобы точнее искали

В далеком светлом будущем:

— вынести sper-машину подальше от серверной куда-нибудь в другое помещение
— сделать машинам нормальные имена в сети (хотя с другой стороны народ уже привык)
— подумать о rsync вместо scp (но с другой стороны — инкрементальных бэкапов у меня — пока нет, сеть локальная, так что…)

Но я сегодня слишком замучен — поэтому отложу до лучших времен. Хорошее сегодня лучше, чем лучшее никогда :)

Разумеется, пытливый ум догадается, что по scp можно бэкапить не только mysql-базы, но и все остальное.

Оставьте комментарий