Простой backup

6th Январь 2012 | Категории: Сервер | Метки: ,

После того, как я чуть не потерял все свои труды, я твёрдо решил настроить систему автоматического резервного копирования. Или backup. Давайте рассмотрим требования к идеальной системе, и начнем писать свою собственную на bash.

Делать резервную копию файлов, баз данных.

Собственно то, ради чего нам и нужен backup — что бы в экстренном случае мы могли восстановить все данные.

Паковать все в архивы.

Место не резиновое. К тому же, куча мелких файлов копируется куда дольше, чем один файл.

Делать инкрементные архивы.

Полезная опция при создании резервной копии исходников. Зачем сохранять каждый раз одни и те же файлы, если они не меняются?

Очищать старые копии.

Очень сложно представить ситуацию, когда нужен архив, сделанный именно 23 дня назад (конечно же, если он не ключевой при инкрементном backup).

Сохранять ключевые точки.

Обычно в сложных системах используется такая схема: ежемесячные – сохраняем данные на 1 число каждого месяца и храним последние 6 копий; еженедельные – сохраняем каждый понедельник данные и храним последние 4 копии; ежедневные backup – храним последние 7 копий.

«Хранить яйца в разных корзинах».

Не стоит хранить резервные копии на том же самом сервере, что и ваши сайты: если что-нибудь случится с самим сервером, вы потеряете и текущие данные и резервные копии. Не стоит хранить резервные копии и на сервере в том же дата центре: пожар, нашествие саранчи или метеоритный дождь могут превратить дорогое оборудование в груду железок, без возможности какого-либо восстановления. В идеале ключевые backup храним как минимум в другом дата центре, а лучше – в другой стране. Если у вас хороший канал, можно периодически сохранять копии у себя локально (на RAID 0 массив).

Backup в облако.

Наилучшим решением, с точки зрения надежности, будет использование облачного хостинга под backup. Возможно использование как бесплатных решений (Dropbox), так и платных (Amazon S3). Мало того, что вы сможете получить доступ к своим архивам с высокой скоростью почти из любой точки земного шара, так еще сами архивы защищены от форс-мажорной утери.

Конечно, в идеале приведенное описание звучит красиво. Решения, которые могут выполнить почти все пункты или дороги, или сложны в настройке. Или и то, и другое вместе взятое. Мы не ищем легких путей, поэтому будем писать свою систему резервного копирования. И начнем с первого пункта: простое резервное копирование – всего два скрипта на bash. Написание скриптов на bash не менее увлекательное занятие, чем программирование на PHP, или составление SQL запросов.

Условности.

Каждый backup мы будем сохранять в каталоге /var/backup/{database|sites}/дата. Для MySQL – в каждом каталоге с текущей датой будет создан архив с названием БД. Для сайтов – в каждом каталоге с текущей датой будет создан архив с названием сайта. Сайты находятся в каталоге /var/www/sites.

База.

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

#!/bin/bash
USER="root"
PASSWORD="password"
mkdir -p /var/backup/database/`date +%F`;
for DB in `mysql -u$USER -p$PASSWORD -N -e 'show databases' | awk '{print $1}'`; do
	echo "${DB} Backup";
	mysqldump --user=$USER --host=$HOST --password=$PASSWORD ${DB} --skip-lock-tables | gzip > /var/backup/database/`date +%F`/${DB}.sql.gz;
done

Сайты.

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

#!/bin/bash
mkdir -p /var/backup/sites/`date +%F`;
for DIR in `ls /var/www/sites | awk '{print $1}'`; do
	echo "${DIR} Backup";
	tar cvzf /var/backup/sites/`date +%F`/${DIR}.tar.gz -C / var/www/sites/${DIR}/
done

Subscribe without commenting


  1. 7th Январь 2012 в 16:02

    mysqldump лучше с ключиком —skip-lock-tables делать.
    Аналогично бэкаплю, на ftp шару, подмоутенную через curlftpfs

  2. Тарлюн Максим
    18th Январь 2012 в 20:13

    @IAD
    Спасибо, подправил.
    Хотя лучше так не делать, так как целостность данных в backup может быть нарушена.
    В первых: если у вас ночью нагрузка минимальна — то несколько запросов могут и подождать.
    Во вторых: можно отключить сайты, повесив заглушку «сайт на обслуживании» — так поступают крупные проекты. с большими базами.
    В третьих: сделать сервер для репликации и снимать backup с него.

  3. 18th Январь 2012 в 21:53

    угу, обычно слейв бэкапят. А лучше просто иметь слейв. Но, если не юзаются транзакции — целостность под угрозой.
    В любом случае восстановление из бекапа — это уже провал(Последние данные уже потеряны). Для бэкапа сайтов с 10 посетителями в сутки — вполне нормально =)

  4. JustSoul
    30th Август 2013 в 10:42

    Подскажите пожалуйста, как исключить из бекапа папки с логами (и/или другими дерикториями)?
    К примеру сайты у меня хранятся так:
    /home/www/
    …example.com/
    ……logs/
    ……htdocs/
    …example2.com/
    ……logs/
    ……htdocs/
    И т.п…
    Или лучше перенести логи в другую директорию (хотелось бы без переноса) или для каждого отдельного сайта в этом скрипте прописывать свою команду?

  5. Тарлюн Максим
    30th Август 2013 в 11:21

    Документация по tar:
    Когда вы задаете опцию '--exclude=шаблон', tar игнорирует файлы, соответствующие шаблону, который может быть отдельным файлом или более сложным выражением. Таким образом, если вы вызываете tar с помощью 'tar --create --exclude=*/o', файлы, имена которых кончаются на '.o', не включаются в архив.

    Другие полезные ключи:
    Можно в ненужные каталоги добавить произвольный ФАЙЛ (например backup.ignore). И добавить ключ:
    --exclude-tag=ФАЙЛ исключать каталоги, содержащие ФАЙЛ, за исключением самого ФАЙЛА
    --exclude-tag-all=ФАЙЛ исключать каталоги с ФАЙЛОМ
    --exclude-tag-under=ФАЙЛ исключать всё содержимое каталогов, содержащих ФАЙЛ

    Фильтр по дате, файлы новее 1 Aug 2013. Полезно при создании инкрементных копий
    --newer '1 Aug 2013'