Делать бекапы рекомендуется ассоциацией психиатров, т.к. нервные клетки не восстанавливаются :). В этом посте предлагаю один из возможных способов бекапа системных файлов, баз данных и директорий с сайтами.
Я бекаплюсь по такой схеме:
В начале каждого скрипта есть набор переменных, в которых просто меняете значения на свои.
Скрипт для бекапа mysql-базы. Мне бекапить все базы не надо, поэтому я в переменной DB_LIST храню список тех баз, что необходимо сохранить. Файлы старше 10 дней (переменная FILES_OLDER_THAN) автоматически удаляются.
### system setup ### GZIP="$(which gzip)" NOW=$(date +"%d-%m-%Y") ### mysql setup ### # view all dbs: mysql -u admin -h localhost -p -Bse 'show databases' DB_LIST="db1 db2 db3" DB_USER="root" DB_PASS="qwerty" DB_HOST="localhost" MYSQL="$(which mysql)" MYSQLDUMP="$(which mysqldump)" DB_BACKUP_DIR=/home/proft/backup/db FILES_OLDER_THAN=10 #days # backup dbs for DB in $DB_LIST; do DB_DIR=$DB_BACKUP_DIR/$DB if [ ! -d "$DB_DIR" ]; then mkdir -p $DB_DIR fi FILE=$DB_DIR/mysql-$DB-$NOW.gz $MYSQLDUMP -u $DB_USER -h $DB_HOST -p$DB_PASS $DB | $GZIP -9 > $FILE done # delete files older than $DB_OLDER_THAN days find $DB_BACKUP_DIR -type f -mtime +$FILES_OLDER_THAN -exec rm {} \;
Скрипт который бекапит содержимое папок с сайтами. Я хочу что-бы каждый архив имел вид www-Имя_Сайта-Дата.tar.gz. Первая идея которая пришла в голову - ассоциативные массивы (хэши), в ключе хранится Имя_Сайта в значении - путь к сайту в файловой системе. Но bash поддерживает хеши начиная с версии 4, а на сервере стоит bash 3.2, делать апдейт я поленился :). Второе решение, более примитивное, завести два отдельных массива, в одном хранить названия сайтов (переменная WWW_NAMES), в другом - пути к сайтам (переменная WWW_PATHS). Файлы старше 10 дней (переменная FILES_OLDER_THAN) автоматически удаляются.
### system setup ### GZIP="$(which gzip)" NOW=$(date +"%d-%m-%Y") ### www dirs setup ### WWW_NAMES=("www1" "www2" "www3") WWW_PATHS=("/srv/www/www1/" "/srv/www/www2/" "/srv/www/www3/") WWW_BACKUP_DIR=/home/proft/backup/www FILES_OLDER_THAN=10 #days # backup www for WWW in ${!WWW_NAMES[*]}; do WWW_DIR=$WWW_BACKUP_DIR/${WWW_NAMES[$WWW]} if [ ! -d "$WWW_DIR" ]; then mkdir -p $WWW_DIR fi FILE=$WWW_DIR/www-${WWW_NAMES[$WWW]}-$NOW.tar.gz tar -zcf $FILE ${WWW_PATHS[$WWW]} done # delete files older than $DB_OLDER_THAN days find $WWW_BACKUP_DIR -type f -mtime +$FILES_OLDER_THAN -exec rm {} \;
Скрипт бекапа системных папок похож один в один на предыдущий, только в массиве SYS_NAMES хранятся имена системных папок, а в массиве SYS_PATHS пути к ним.
### system setup ### GZIP="$(which gzip)" NOW=$(date +"%d-%m-%Y") ### sys dirs setup ### SYS_NAMES=("etc") SYS_PATHS=("/etc/") SYS_BACKUP_DIR=/home/proft/backup/sys FILES_OLDER_THAN=10 # backup sys for SYS in ${!SYS_NAMES[*]}; do SYS_DIR=$SYS_BACKUP_DIR/${SYS_NAMES[$SYS]} if [ ! -d "$SYS_DIR" ]; then mkdir -p $SYS_DIR fi FILE=$SYS_DIR/${SYS_NAMES[$SYS]}-$NOW.tar.gz tar -zcf $FILE ${SYS_PATHS[$SYS]} done # delete files older than $DB_OLDER_THAN days find $SYS_BACKUP_DIR -type f -mtime +$FILES_OLDER_THAN -exec rm {} \;
Запускаем cron:
crontab -e
и говорим когда запускать скрипты
20 0 */2 * * /home/proft/backup/db.sh >/dev/null 2>&1 40 0 */5 * * /home/proft/backup/www.sh >/dev/null 2>&1 0 1 1 * * root /home/proft/backup/sys.sh >/dev/null 2>&1
C основной частью процесса бекапинга покончено, теперь осталось настроить копирование последних архивов на другую машину. Для этого нам понадобится скрипт, на сервере с бекапами, который будет возвращать полный путь к последним бекапам, этот путь мы бдем скармливать scp на другой машине:
DB_BACKUP_DIR=/home/proft/backup/db WWW_BACKUP_DIR=/home/proft/backup/www SYS_BACKUP_DIR=/home/proft/backup/sys # list last backups for dir in $DB_BACKUP_DIR/* $WWW_BACKUP_DIR/* $SYS_BACKUP_DIR/*; do last_file=`ls -t1 $dir | head -n1` echo $dir/$last_file done
Скрипт который находится на другой машине, которая конектится по ssh к основному серверу и забирает последние архивы.
DB_BACKUP_DIR=/home/proft/backup/db WWW_BACKUP_DIR=/home/proft/backup/www SYS_BACKUP_DIR=/home/proft/backup/sys # list last backups for dir in $DB_BACKUP_DIR/* $WWW_BACKUP_DIR/* $SYS_BACKUP_DIR/*; do last_file=`ls -t1 $dir | head -n1` echo $dir/$last_file done
В скрипте есть один изъян - он на протяжении месяца забирает один и тот же файл несколько раз (системные папки, которые бекапятся раз в месяц), но меня это почти устраивает и что-то допиливать пока лень.
Буду рад советам, рекомендациям бывалых админов.
Все скрипты одним архивом, пользуйтесь на здоровье :).
Дополнительное чтиво: