Для работы с бекап хостингом потребуется установка утилиты curlftpfs .
При помощи данной утилиты мы сможем примонтировать диск бекап хостинга к ОС и пользоваться как папкой, для этого потребуется создать директорию к примеру:
mkdir␣-p␣/home/ftp_share,
Команда монтирования выглядит следующим образом :
curlftpfs␣ftp://45.143.139.249␣-o␣user=login:password
(где login — логин доступа к ftp, password — пароль)
У нас появится папка ftp_share в директории /home
Теперь при помощи утилиты scp можно перекачивать файлы на прямую на ftp.
scp␣-r␣/директория которую нужно скачать/␣/директория куда надо скачать/
(примерно так: scp -r /root/magicbook/ /home/ftp_share/)
Можно пользоваться архиватором — потребуется установить zip
Команда добавления каталога в архив:
zip␣-r␣имя архива.zip␣/имя директори/ (zip␣-r␣lasershick.zip␣/root/magickbook/)
- получим сжатый архив каталога, который потом можно будет скачать на бекап сервер для экономии места
Можно автоматизировать процесс по средством скрипта
Для начала создадим и откроем скрипт
nano backup-script
Теперь в скрипте добавим строку
#!/bin/bash
Объявим некоторые переменные.
TN — TASKNAME — имя задания.Используется для вывода в лог и определения названия файла.
Наименование заданий писать надо без пробелов, желательно в латинице, если не хотите проблем с кодировкой и неправильными параметрами команд.
TN=docs-daily
OF — Output File — имя выходного файла. Имя выходного файла будет исходить из даты и времени выполнения.
OF=$(date +'%d-%b-%Y-%R').tar.gz
Объявляем переменную с путем к файлу лога, и далее все сообщения об ошибках и остальном будем выводить в лог.
LOGFILE=/var/log/backup.log
Сделаем запись в лог о начале бэкапа (дата, время, имя задания)
echo $LOGFILE
echo "=====================================================" $LOGFILE
echo "$(date +'%d-%b-%Y %R')" $LOGFILE
echo "Задание \"$TN\" запущено..." $LOGFILE
Есть проблема в том что если указывать в параметрах команд (напр. tar) имена каталогов с пробелами, скрипт срабатывает с ошибкой. Решение найдено на просторах интернета — операционная система linux использует пробел в качестве стандартного разделителя параметров команды. Переопределим стандартный разделитель (хранится в переменной $IFS) отличным от пробела, например \n<\b> – знаком переноса строки.
Запоминаем старое значение стандартного разделителя
OLD_IFS=$IFS
Заменяем стандартный разделитель своим
IFS=$'\n'
SRCD — SouRCe Directory — каталог с данными для бэкапа
Теперь можно перечислять несколько каталогов, разделителем будет перенос строк как мы сами указали строкой выше
SRCD="/mnt/source/folder_1
/mnt/source/folder_2
/mnt/source/folder_N"
TGTD — TarGeT Directory — каталог в который будут складываться бэкапы
TGTD="/var/backups/"
Естественно мы понимаем что хранить важные бэкапы только на источнике как минимум легкомысленно. Поэтому оставим копию и на удаленном ресурсе, который будем отдельно монтировать с помощью mount и fstab.
TGTD2="/home/ftp_share/"
Сам процесс архивирования в варианте "Создать новый архив"
tar -czf $TGTD$OF $SRCD $LOGFILE
В переменной "?" ханится статус выполнения последней команды. Сохраним его, чтобы воспользоваться позже.
STATUS=$?
Возвращаем стандартный разделитель к исходному значению
IFS=$OLD_IFS
Теперь добавим условие — если процесс упаковки в архив tar закончился с ошибкой, отправляем сообщение админу, удаляем неудачный файл бекапа. Иначе продолжаем дальше — монтируем сетевую шару и кидаем в нее копию архива. После каждой операции проверяем результат выполнения, пишем логи, и либо продолжаем, либо извещаем админа и прерываем процедуру.
if [[ $STATUS != 0 ]]; then
rm $TGTD$OF $LOGFILE
echo "###########################################" $LOGFILE
echo "### Произошла ошибка! Бэкап не удался. ###" $LOGFILE
echo "###########################################" $LOGFILE
echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не создан" $LOGFILE
else
echo "Файл бэкапа сохранен как \"$TGTD$OF\"" $LOGFILE
echo "Бэкап успешно завершен в $(date +'%R %d-%b-%Y')!" $LOGFILE
echo "Монтирование файловой системы для резервного архива $TGTD_archive" $LOGFILE
mount $TGTD2 $LOGFILE
if [[ $? != 0 ]]; then
echo "#############################################################" $LOGFILE
echo "### Произошла ошибка при монтировании резервного ресурса ###" $LOGFILE
echo "#############################################################" $LOGFILE
echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" $LOGFILE
exit
fi
echo "Начато копирование файла на резервный ресурс" $LOGFILE
cp -f $TGTD$OF /home/ftp_share/ $LOGFILE
if [[ $? != 0 ]]; then
echo "#############################################################" $LOGFILE
echo "### Произошла ошибка при копировании на резервный ресурс ###" $LOGFILE
echo "#############################################################" $LOGFILE
echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" $LOGFILE
else
echo "Копирование файла успешно завершено в $(date +'%R %d-%b-%Y')!" $LOGFILE
echo "Файл скопирован как \"$TGTD_archive$OF\"" $LOGFILE
fi
echo "Размонтирование файловой системы для резервного архива $TGTD_archive" $LOGFILE
umount /home/ftp_share $LOGFILE
echo "Все операции завершены успешно!" $LOGFILE
fi
exit
В процессе мы копируем архив из локального хванилища в удаленное. Естественно, проверяем, что каждая операция успешно завершена, и пишем все в логи.
Возникнет вопрос об удалении лишних бекапов, в этом вопросе поможет утилита find. Команда на поиск и удаление старого бекапа будет выглядеть примерно так:
find /home/ftp_share/ -mmin +700 -delete
(команда␣место_где_ищем␣параметр_поиска␣значение_параметра␣действие), в данном случае параметр поиска по колличесву минут, для установки поиска по кодичеству дне пишем -mtime
В файле fstab строка описывающая подключение шары Windows;
curlftpfs# ftp://логин:пароль@хост/ /home/ftp_share fuse rw,uid=500,user,noauto,nonempty 0 0
Теперь осталось только добавить задание в cron. Это можно сделать с помощью файла /etc/crontab.
В ходе обсуждений затронули проблему разрастания логов. Пошел по простейшему (на мой взгляд) пути: будем хранить только последние N строк лога, например 300. В скрипт добавятся две строки, в которых мы сохраним последние 300 строк лога во временный файл, потом затрем им лог
tail -n 300 $LOGFILE /tmp/unique_fantastic_filename.tmp
mv -f /tmp/unique_fantastic_filename.tmp $LOGFILE
Примерный скрипт для бекапирования:
#!/bin/bash
TN=docs-daily
OF=$(date +'%d-%b-%Y-%R').tar.gz
LOGFILE=/var/log/backup.log
echo $LOGFILE
echo "=====================================================" $LOGFILE
echo "$(date +'%d-%b-%Y %R')" $LOGFILE
echo "Задание \"$TN\" запущено..." $LOGFILE
OLD_IFS=$IFS
IFS=$'\n'
SRCD="/mnt/source/folder_1"
TGTD="/var/backups/"
TGTD2="/home/ftp_share/"
tar -zcf $TGTD$OF $SRCD $LOGFILE
STATUS=$?
IFS=$OLD_IFS
if [[ $STATUS != 0 ]]; then
rm $TGTD$OF $LOGFILE
echo "###########################################" $LOGFILE
echo "### Произошла ошибка! Бэкап не удался. ###" $LOGFILE
echo "###########################################" $LOGFILE
echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не создан" $LOGFILE
else
echo "Файл бэкапа сохранен как \"$TGTD$OF\"" $LOGFILE
echo "Бэкап успешно завершен в $(date +'%R %d-%b-%Y')!" $LOGFILE
echo "Монтирование файловой системы для резервного архива $TGTD_archive" $LOGFILE
mount $TGTD2 $LOGFILE
if [[ $? != 0 ]]; then
echo "#############################################################" $LOGFILE
echo "### Произошла ошибка при монтировании резервного ресурса ###" $LOGFILE
echo "#############################################################" $LOGFILE
echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" $LOGFILE
exit
fi
echo "Начато копирование файла на резервный ресурс" ;$LOGFILE
cp -f $TGTD$OF /home/ftp_share/ $LOGFILE
if [[ $? != 0 ]]; then
echo "#############################################################" $LOGFILE
echo "### Произошла ошибка при копировании на резервный ресурс ###" $LOGFILE
echo "#############################################################" $LOGFILE
echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" $LOGFILE
else
echo "Копирование файла успешно завершено в $(date +'%R %d-%b-%Y')!" $LOGFILE
echo "Файл скопирован как \"$TGTD_archive$OF\"" $LOGFILE
fi
echo "Начало удаления лишнего" $LOGFILE
find /home/ftp_share/ -mmin +700 -delete $LOGFILE
if [[ $? != 0 ]]; then
echo "ERROR-ERROR-ERROR" $LOGFILE
echo "$(date +'%d-%b-%Y %R%nффйл') Неполучилось" $LOGFILE
else
echo "Удаление лишнего выполнено"$LOGFILE
fi
echo "Удаление с диска" $LOGFILE
find /var/backups/ -mmin +700 -delete $LOGFILE
if [[ $? != 0 ]]; then
echo "###ERROR###" $LOGFILE
else
echo "Очистка выполнена" $LOGFILE
fi
echo "Размонтирование файловой системы для резервного архива $TGTD_archive" $LOGFILE
umount /home/ftp_share $LOGFILE
echo "Все операции завершены успешно!" $LOGFILE
fi
tail -n 300 $LOGFILE /tmp/unique_fantastic_filename.tmp
mv -f /tmp/unique_fantastic_filename.tmp $LOGFILE
exit
Скрипт пишется индивидуально для каждого свой, этот пример лишь шаблон — его придется самому переписывать для своего удобства