Linux,  Servers

Резервное копирование с ротацией бэкапов. Bash скрипт

Резервное копирование с ротацией бэкапов. Bash скриптВ прошлой статья было рассмотрено упрощенный вариант бэкапа сайта с возможностью загрузить бэкап на сервер FTP.

Со временем у меня возникла потребность сделать более улучшенную версию скрипта для создания бэкапа всего сервера (файлы нескольких сайтов и их БД ), а также загружать на FTP все это хозяйство c помощью cURL, так как на сервере не было установлен FTP клиент и установить его не было возможности. Также нужно было удалять на FTP сервере старые бэкапы, чтобы не засорялось место на диске.

Бэкап сайтов и Баз Данных

Начнем с настроек. Укажем доступы к БД под которыми будем архивировать Базу Данных:

MUSER="root"
MPASS="superpassword"
MHOST="localhost"

Зададим путь к каталогу в котором будем архивировать данные с сайтами и куда будем сохранять временные архивы, до выгрузки на FTP:

SITEDIR=/var/www/sites
BACKUP=/var/www/backup

SITEDIR — все директории с сайтами которые лежат внутри этого каталога будут архивироваться в отдельные архивы. Например есть каталоги /var/www/sites/site1.ru и /var/www/sites/site2.ru — соответственно мы получим два архива site1.ru.tar.gz и site2.ru.tar.gz

Далее устанавливаем текущую дату, чтобы помечать бэкапы и было понятно за какой день они сделаны:

NOW=$(date +%Y%m%d)

Указываем путь к бинарникам:

TAR="$(which tar)"
GZIP="$(which gzip)"
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"

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

mkdir $BACKUP/$NOW

Далее сохраняем в переменную LS список всех сайтов из указанной нами директории SITEDIR, чтобы поочереди их заархивировать.

  1. LS=«$(cd $SITEDIR; ls)»
  2. for site in $LS
  3. do
  4. cd $SITEDIR;
  5. $TAR czf $BACKUP/$NOW/$site.tar.gz $site
  6. done

Синтаксис «$(…)» указывает что нам нужно выполнить команду внутри скобок и результат выполнения присвоить переменной LS. После этого проходим по директориям циклом в котором сначала переходим в эту директорию, а потом архивируем содержимое. В директорию мы заходили для того чтобы были короткие пути в архивах вида:

site1.ru/index.html
site1.ru/css
site1.ru/css/style.css

а не такого вида:

/var/www/sites/site1.ru/index.html
/var/www/sites/site1.ru/css
/var/www/sites/site1.ru/css/style.css

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

ARCHIVESITE=$BACKUP/server-$NOW.tar.gz
cd $BACKUP/$NOW;
$TAR -zcvf $ARCHIVESITE ./

В ARCHIVESITE — указываем что это архив с данными (server) и добавляем дату бэкапа. Потом переходим в директорию NOW и добавляем их в архив.

Теперь можно очистить директорию NOW, для промежуточных бэкапов баз данных.

rm -rf $BACKUP/$NOW/*

В итого у нас получился один архив с данными (файлами) сайтов который покуда лежит в директории ARCHIVESITE. К нему чуть попозже вернемся когда будем загружать бэкапы на FTP.

Переходим дальше к бэкапам Баз Данных.

Изначально подключаемся к MYSQL и просим показать нам список всех БД у данного пользователя. После этого пройдемся циклом по этим базами и заархивируем их и сложим в директорию BACKUP/NOW

  1. DBS=«$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse ‘show databases’)»
  2. for db in $DBS
  3. do
  4. if [ $db != ‘information_schema’ ]
  5. then
  6. FILE=$BACKUP/$NOW/$db.sql.gz
  7. $MYSQLDUMP adddroptable allowkeywords q c u $MUSER h $MHOST p$MPASS $db $i | $GZIP 9 > $FILE
  8. fi
  9. done

Также мы можем отсечь не нужные нам БД, например information_schema которые являются служебными и содержимое их нас не интересует.

Собираем все архивы с БД в один общий и добавляем дату бэкапа

ARCHIVEDB=$BACKUP/mysql-$NOW.tar.gz
cd $BACKUP/$NOW;
$TAR -zcvf $ARCHIVEDB ./

В ARCHIVEDB — указываем что это архив с Базой Данных (mysql) и добавляем дату бэкапа.

Директорию NOW (и все что в ней есть) можно удалять она нам больше не нужна:

rm -rf $BACKUP/$NOW

После всего этого у нас осталось два архива с файлами и данными:

ARCHIVESITE=$BACKUP/server-$NOW.tar.gz
ARCHIVEDB=$BACKUP/mysql-$NOW.tar.gz

Загрузка данных на FTP

Теперь все это дело нужно загрузить как то на FTP, для этих целей мы будем использовать cURL.

Начнем опять же с настроек:

FTPD="dir/to/backup" #директория внутри FTP (вначале и в конце без слеша)
FTPU="user" #имя пользователя
FTPP="password" #пароль
FTPS="site3.ru" #сервер FTP

Задаем количество бэкапов которое нужно сохранять на FTP:

DAYS=5 #дневные бэкапы не считая текущего
MONTHS=3 #месячные бэкапы на первое число месяца не считая текущего

Указываем путь к curl:

CURL="$(which curl)"

Дальше переходим в каталог с нашими бэкапами:

cd $BACKUP

И загружаем их на FTP в указанную в настройках директорию:

$CURL -u $FTPU:$FTPP ftp://$FTPS/$FTPD/ -T "{server-$NOW.tar.gz,mysql-$NOW.tar.gz}" -s

Для удаления лишних бэкапов (которым более 5 дней) запрашиваем список всех файлов в директории на FTP:

LIST="$($CURL -u $FTPU:$FTPP ftp://$FTPS/$FTPD/ -s -l)"

Перебираем все файлы в цикле и смотрим чтобы это были файлы типа server-{date}.tar.gz и mysql-{date}.tar.gz. Если дата не совпадает с разрешенной (последние N дней и 1 число последних N месяцев) мы их удаляем:

  1. for li in $LIST
  2. do
  3. EXIST=0
  4. if [ «$li» = «.» ] || [ «$li» = «..» ]
  5. then
  6. continue
  7. fi
  8. for day in `seq 0 $DAYS`
  9. do
  10. d=«$(date +%Y%m%d -d «$day days ago«)»
  11. if [ «server-$d.tar.gz» = «$li» ] || [ «mysql-$d.tar.gz» = «$li» ]
  12. then
  13. EXIST=1
  14. continue
  15. fi
  16. done
  17. for month in `seq 0 $MONTHS`
  18. do
  19. d=«$(date +%Y%m01 -d «$month month ago«)»
  20. if [ «server-$d.tar.gz» = $li ] || [ «mysql-$d.tar.gz» = $li ]
  21. then
  22. EXIST=1
  23. continue
  24. fi
  25. done
  26. if [ $EXIST eq 0 ]
  27. then
  28. $CURL u $FTPU:$FTPP ftp://$FTPS/$FTPD/ -s -X «DELE $li»
  29. fi
  30. done

И очищаем директорию BACKUP:

rm -rf $BACKUP/*

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

Если есть предложения по улучшению или замечания — пишите в комментариях

Attachments

Добавить комментарий

Ваш e-mail не будет опубликован.