[Сценарий] Резервное копирование БД и каталогов сервера (для Linux)

Не требует установки программ или изменения файлов

Модераторы: immortal, newz20

skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

[Сценарий] Резервное копирование БД и каталогов сервера (для Linux)

Сообщение skysilver » Ср мар 11, 2015 4:45 pm

Написал сценарий для ежедневного создания резервных копий БД и каталогов linux-сервера (у меня ОС Debian).

Возможности:
  • архивирование каталогов (tar);
  • создание дампов БД MySQL (mysqldump);
  • запись созданных архивов на локальный диск;
  • копирование архивов в облако (Яндекс.Диск);
  • получение сведений о занятом и доступном месте на Яндекс.Диск;
  • ротация экземпляров резервных копий и на локальном диске и в облаке (хранятся N последних копий, остальные удаляются);
  • автоматическое создание необходимых каталогов;
  • логирование выполняемых действий.
Описание:
Архивы сохраняются на локальный диск и загружаются в облако (на Яндекс.Диск средствами REST API и OAuth-авторизации). Предусмотрена ротация архивных копий (хранится не более заданного числа архивов, остальные удаляются). На каждый ежедневный архив создается собственный каталог с именем вида "год-месяц-день", в который помещаются файлы с архивами БД и каталогов.

Для использования облачного хранилища Яндекс.Диск предварительно необходимо авторизоваться на Яндексе и создать приложение здесь (указать название приложения, дать все права в разделе Яндекс.Диск REST API, в Callback URL подставить URL для разработки). В свойствах созданного приложения будут приведены ID и пароль приложения. OAuth-токен можно получить вручную согласно этой инструкции. Либо, оставив поле token в $yandexDiskConfig сценария пустым, указать в этом свои логин и пароль для доступа к сервисам Яндекса, тогда токен будет запрашиваться у Яндекса при каждом запуске сценария. Рекомендую запросить токен таким образом однократно, а в дальнейшем полученный токен указывать непосредственно в $yandexDiskConfig), не дергая Яндекс лишними запросами.

Если имеется несколько учеток к Яндекс.Диск, то достаточно создать только одно приложение и указывать его ID и пароль при получении токена для другой учетки. Таким образом можно копировать архивы (или еще чего) на разные Яндекс.Диски.

Набор параметров:
  • numberOfCloudBackups - количество хранимых бэкапов в облаке
  • numberOfLocalBackups- количество хранимых бэкапов локально
  • cloudBackupFolder- каталог для бэкапов в облаке (например, /backups)
  • localBackupFolder- количество хранимых бэкапов в облаке (в днях)
  • numberOfCloudBackups - локальный каталог для бэкапов (например, /home/skysilver/backups)
  • shellScript - путь к вспомогательному shell-скрипту
  • логин и пароль пользователя MySQL
  • имена архвивируемых БД
  • архивируемые каталоги (путь)
  • реквизиты доступа к Яндекс.Диск
    • app_id - идентификатор приложения
    • app_secret - секретный ключ (пароль) приложения
    • token - OAuth-токен
    • login - логин пользователя
    • password - пароль пользователя
Замечания по применению:
1. Т.к. процесс архивирования и копирования в облако занимает приличное время, и чтобы основной цикл не ожидал завершения работы сценария, то запускать его нужно в фоне примерно так (для метода onNewMinute):

Код: Выделить всё

if(timeIs('06:05')) {
    $command = "php -q ./objects/index.php script:backupServer";
    shell_exec("nohup $command > /dev/null & echo $!");
}
2. У пользователя www-data (все циклы у меня запущены от его имени) нет права чтения некоторых каталогов. Поэтому, чтобы была возможность такие каталоги архивировать, для запуска линуксовых команд используется shell-скрипт, который благодаря sudo может запускаться с правами root под пользователем www-data. Чтобы дать пользователю www-data возможность запускать этот скрипт от root, необходимо в /etc/sudoers добавить строку

Код: Выделить всё

www-data ALL=(root) NOPASSWD: /var/www/lib/backup.sh
3. Рекомендуется в phpMyAdmin создать отдельного пользователя для целей резервного копирования БД только с правами чтения на все требумые БД (из моих наблюдений, достаточно привилегий SELECT, SHOW DATABASES, LOCK TABLES).
4. Все параметры, требуемые в сценарии, у меня хранятся в свойствах объектов и в явном виде в коде сценария не указываются.
5. В коде сценария используется две функции - arraySort(&$data, $sortpath) и removeDirectory($dir), которые помещены в файл my.class.php вместе с другими пользовательскими функциями.
6. Класс для работы с Яндекс.Диск через REST API размещается в файле yandex_disk.class.php (в данном классе также есть много интересных функций по работе с облачным хранилищем Яндекса).
7. Файлы my.class.php, yandex_disk.class.php и backup.sh положить в /var/www/lib/.
8. Старался максимально комментировать код сценария, чтобы возникало меньше вопросов. :)

Обновление от 2.06.2015 г.

Порядок установки:
  1. 0. Убедиться, что в ОС есть пакеты tar, gzip и mysqldump. Предполагается, что Яндекс.Диск уже имеется, и логин-пароль к нему соответсвенно тоже.
    1. Скачать и распаковать прикрепленный к посту архив. В нем лежит 4 файла: my.class.php, yandex_disk.class.php, backup.sh и backupServer.php.
    2. Файлы my.class.php, yandex_disk.class.php положить в каталог lib и дать им права доступа и назначить владельца такие же, как и у других файлов в этом каталоге. Убедиться, что в содержимое файлов не добавились символы ^M в конце строк (такое бывает, если использовать для редактирования виндовый блокнот и т.п.).
    3. Файл backup.sh также положить в каталог lib и дать ему права доступа и назначить владельца такие же, как и у других файлов в этом каталоге.
    Убедиться, что в содержимое файла не добавились символы ^M в конце строк. Затем дать пользователю www-data полномочия запускать этот shell-скрипт от имени root. Для этого в файле /etc/sudoers добавить строку

    Код: Выделить всё

    www-data ALL=(root) NOPASSWD: /var/www/lib/backup.sh
    Файл /etc/sudoers лучше редактировать с помощью команды visudo.
    4. Создать свое приложение на Яндексе. Получить OAuth-токен авторизации на Яндекс.Диске, ID и пароль созданного приложения. (см. п. "Описание").
    5. Создать сценарий backupServer и вставить в него код из файла backupServer.php. Отредактировать код сценария под себя согласно комментариям в нем. Необходимо указать значения всех параметров, описанных в пункте "Набор параметров" этого поста. Значения параметров можно либо вписать прямо в код сценария, либо получать через getGlobal у свойств заранее созданного объекта.
    6. По окончанию редактирирования сценария backupServer попробовать его запустить на выполенение и посмотреть результат. Если все ОК, то можно в метод onNewMinute добавить код на выполнение этого сценария в определенное время (см. п. "Замечания по применению"). Если что-то пошло не так, то наблюдать за логами Apache, DebMes на появление каких-либо ошибок.
    7. В XRay убедиться, что данные имеются события о процессе резервного копирования.
Исходные коды:
Прикрепил файлами, иначе длинная портянка получается. :)
backupServer.zip
Код сценария backupServer и сопутствующие файлы.
(11.14 КБ) 549 скачиваний
Если включить полное логирование, то в XRay-Debug будет примерно так:
СпойлерПоказать
06:12:21 TRACE [script.backupServer]: Завершение резервного копирования данных на сервере.
06:12:21 TRACE [script.backupServer]: Архивов меньше (или равно) требуемого количества. Ничего не удаляем.
06:12:21 TRACE [script.backupServer]: Найдено 6 каталогов на Яндекс.Диске.
06:12:21 TRACE [script.backupServer]: Архивов меньше (или равно) требуемого количества. Ничего не удаляем.
06:12:21 TRACE [script.backupServer]: Найдено 6 каталогов на локальном диске.
06:12:21 TRACE [script.backupServer]: Этап 3. Ротация бэкапов на локальном диске и в облаке.
06:12:19 TRACE [script.backupServer]: Загрузка на Яндекс.Диск: mysql_db_myfin2_2015-03-11_06-05.sql.gz [3502 Байт]
06:12:17 TRACE [script.backupServer]: Загрузка на Яндекс.Диск: mysql_db_myfin1_2015-03-11_06-05.sql.gz [122958 Байт]
06:12:11 TRACE [script.backupServer]: Загрузка на Яндекс.Диск: mysql_db_ihome_2015-03-11_06-05.sql.gz [6117289 Байт]
06:10:13 TRACE [script.backupServer]: Загрузка на Яндекс.Диск: files_www_2015-03-11_06-05.tar.gz [246780921 Байт]
06:10:05 TRACE [script.backupServer]: Загрузка на Яндекс.Диск: files_mysql_2015-03-11_06-05.tar.gz [12461525 Байт]
06:09:55 TRACE [script.backupServer]: Загрузка на Яндекс.Диск: files_logs_2015-03-11_06-05.tar.gz [18591556 Байт]
06:09:53 TRACE [script.backupServer]: Загрузка на Яндекс.Диск: files_etc_2015-03-11_06-05.tar.gz [663266 Байт]
06:09:53 TRACE [script.backupServer]: Каталог для ежедневного бэкапа успешно создан.
06:09:52 TRACE [script.backupServer]: Создаем каталог для ежедневного бэкапа /backups/2015-03-11 на Яндекс.Диске.
06:09:52 TRACE [script.backupServer]: Общий каталог для бэкапов уже создан на Яндекс.Диске.
06:09:52 TRACE [script.backupServer]: Свободно: 7.38 ГБ.
06:09:52 TRACE [script.backupServer]: Занято данными: 2.62 ГБ.
06:09:52 TRACE [script.backupServer]: Всего места на Яндекс.Диске: 10 ГБ.
06:09:51 TRACE [script.backupServer]: Этап 2. Копирование локального бэкапа в облако.
06:09:51 TRACE [script.backupServer]: Резервная копия каталога www успешно создана на локальном диске.
06:06:04 TRACE [script.backupServer]: Резервная копия каталога logs успешно создана на локальном диске.
06:05:44 TRACE [script.backupServer]: Резервная копия каталога mysql успешно создана на локальном диске.
06:05:19 TRACE [script.backupServer]: Резервная копия каталога etc успешно создана на локальном диске.
06:05:18 TRACE [script.backupServer]: Резервная копия БД db_ihome успешно создана на локальном диске.
06:05:10 TRACE [script.backupServer]: Резервная копия БД db_myfin2 успешно создана на локальном диске.
06:05:10 TRACE [script.backupServer]: Резервная копия БД db_myfin1 успешно создана на локальном диске.
06:05:10 TRACE [script.backupServer]: Каталог для ежедневного бэкапа успешно создан.
06:05:10 TRACE [script.backupServer]: Создаем каталог для ежедневного бэкапа /home/skysilver/backups/2015-03-11 на локальном диске.
06:05:10 TRACE [script.backupServer]: Общий каталог для бэкапов уже создан на локальном диске.
06:05:10 TRACE [script.backupServer]: Этап 1. Архивация БД и каталогов сервера на локальный диск.
06:05:10 TRACE [script.backupServer]: Начало резервного копирования данных на сервере.
С уважением, skysilver.
Последний раз редактировалось skysilver Вт июн 02, 2015 11:52 am, всего редактировалось 1 раз.
За это сообщение автора skysilver поблагодарили (всего 14):
Bagir (Ср мар 11, 2015 7:25 pm) • Amarok (Чт мар 12, 2015 10:00 am) • Vittaly (Чт мар 12, 2015 12:38 pm) • alexsmol (Чт мар 12, 2015 5:26 pm) • dmw (Пт мар 13, 2015 1:19 pm) • PAV (Ср апр 08, 2015 10:30 am) • mirsum (Вт июн 02, 2015 11:04 pm) • slgeo (Сб июл 25, 2015 2:27 pm) • ipz (Вс дек 20, 2015 11:13 pm) • Pacific (Вт ноя 01, 2016 1:32 pm) и ещё 4
Рейтинг: 16.28%
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
Аватара пользователя
Bagir
Сообщения: 1614
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение Bagir » Ср мар 11, 2015 7:27 pm

Спасибо за труды. Буду разбираться. И отдельное спасибо за идею запуска параллельного процесса из цикла.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
PAV
Сообщения: 949
Зарегистрирован: Пт дек 06, 2013 11:30 am
Откуда: Москва
Благодарил (а): 68 раз
Поблагодарили: 94 раза

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение PAV » Пт мар 13, 2015 11:43 am

Спасибо большое, тоже покопаюсь.
А не пробовали на dropbox все кидать, нет у вас работающего алгоритма.
А то никак не могу мой ЦВ MyCloud с дропбоксом подружить
skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение skysilver » Пт мар 13, 2015 11:48 am

Пожалуйста. С другими облачными хранилищами я не ковырялся, не было необходимости. Но уверен, что все давно уже решено, главное найти нужный класс (скрипт) на просторах интернета и заменить несколько строк в моём сценарии.
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
dmw
Сообщения: 469
Зарегистрирован: Вт мар 12, 2013 1:22 am
Благодарил (а): 41 раз
Поблагодарили: 81 раз

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение dmw » Пт мар 13, 2015 1:19 pm

Былобы совсем прекрасно еслиб сделали его в виде приложения для мартека дополнений.
skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение skysilver » Пт мар 13, 2015 1:46 pm

Да я бы с радостью, но отсутствие опыта и свободного времени не позволяет. Может, из коллег по форуму кто возьмется. :)
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
Anton_kulibin
Сообщения: 354
Зарегистрирован: Вт окт 09, 2012 8:05 am
Откуда: Луза Кировская обл. Россия
Благодарил (а): 20 раз
Поблагодарили: 34 раза

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение Anton_kulibin » Сб мар 14, 2015 8:26 pm

Дмитрию большой респект за проделанную работу. Со всем разобрался, но каталоги у меня не архивирует. Не запускается вообще скрипт, даже от рута. Что-то причину не могу выяснить. Даже все права выставил на запуск.

Код: Выделить всё

20:34:23 ERROR [script.backupServer]: Резервная копия каталога www не создана: Array (at /media/data/public_html/modules/scripts/scripts.class.php(139) : eval()'d code:158) 
20:34:23 ERROR [script.backupServer]: Резервная копия каталога logs не создана: Array (at /media/data/public_html/modules/scripts/scripts.class.php(139) : eval()'d code:158) 
20:34:23 ERROR [script.backupServer]: Резервная копия каталога mysql не создана: Array (at /media/data/public_html/modules/scripts/scripts.class.php(139) : eval()'d code:158) 
Linux версия. Ubuntu Server 16.04+2xArduinoMega+Eth_GW_Mysensors_10node+WeatherStation+Xiaomi
CONNECT
skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение skysilver » Сб мар 14, 2015 10:32 pm

Anton_kulibin писал(а):но каталоги у меня не архивирует
А пакет tar установлен? Архивация каталогов выполняется командой sudo tar -czpPf /путь_к_файлу_архива /путь_к_архивируемой папке. Например так:

Код: Выделить всё

sudo tar -czpPf /home/my_etc_backup.tar.gz /etc
Для начала нужно убедиться, что эта команда работает правильно, запустив ее из консоли.
Следующий шаг - протестировать работу скрипта backup.sh в консоли. От root-a запускаем так:

Код: Выделить всё

sudo /var/www/lib/backup.sh -czpPf /home/my_etc_backup.tar.gz /etc
Для проверки запуска от имени www-data можно создать и запустить тестовый сценарий с кодом:

Код: Выделить всё

$cmd = "sudo /var/www/lib/backup.sh -czpPf /home/my_etc_backup.tar.gz /etc";
var_dump($cmd);
exec($cmd, $out);
var_dump($out);
При этом главный цикл MajorDoMo должен быть запущен, конечно, от имени www-data.
Ну и в логах апача, я думаю, что-то должно быть по этому поводу. ;)
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
Anton_kulibin
Сообщения: 354
Зарегистрирован: Вт окт 09, 2012 8:05 am
Откуда: Луза Кировская обл. Россия
Благодарил (а): 20 раз
Поблагодарили: 34 раза

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение Anton_kulibin » Вс мар 15, 2015 9:23 am

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

Немного сценарий поправил, т.к. на сервере у меня есть приложение яндекс.диска, я просто архивирую в его папку, а дальше он сам все делает. Т.е. оставил все кроме закачки на диск.
Вложения
ошибка в скрипте.png
ошибка в скрипте.png (92.69 КБ) 22111 просмотров
Linux версия. Ubuntu Server 16.04+2xArduinoMega+Eth_GW_Mysensors_10node+WeatherStation+Xiaomi
CONNECT
gagarin74
Сообщения: 330
Зарегистрирован: Пн апр 06, 2015 9:51 am
Благодарил (а): 37 раз
Поблагодарили: 22 раза

Re: Резервное копирование БД и каталогов сервера (для Linux)

Сообщение gagarin74 » Вс апр 26, 2015 8:11 pm

Тема шикарная!!!!!
Но почитал и погруснел:(
А открыл скрипты и заплакал :( Я в жизни ни когда их не настрою.
Мне яндекс облака не надо. Мне достаточно что бы это все в локалку уходило.
Может есть вариант попроще?
сетевой диск примонтировал.
Теперь что бы раз в сутки всё хозяйство копировалось.К имени файлу добавить дату и время.
Всё больше мне не нужно!!!!
Может подсобите ?
Ответить