OSBoy notes.

Записки обо всём...

Скрипт периодического резервного копирования сайта

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

#!/bin/sh

# Задаём путь к файлам нашего сайта
# и к директории для хранения бэкапов:
SITEBACKUPDIR=/path/to/backups/mysite.ru
SITEDIR=/www/mysite.ru

# Задаём количество последних бэкапов, которые будем хранить:
NUMBACKUPS=6

# Если директория бэкапов не существует
# (вдруг случайно потёрли?), создаём её:
if [ -d $SITEBACKUPDIR ]
then :
else
   mkdir -p $SITEBACKUPDIR
fi

# Переходим в директорию нашего сайта и снимаем дамп базы данных:
cd $SITEDIR
mysqldump -uUSER -pPASSWORD --databases --add-drop-table --quick DB_NAME > db_backup.sql

# Здесь USER и PASSWORD - имя и пароль пользователя БД;
# DB_NAME - база нашего сайта;
# --databases - позволяет воссоздать базу с нуля, если она будет
# отсутствовать;
# --add-drop-table - будет очищать базу перед восстановлением,
# что позволит избежать возможных проблем;
# --quick - пишем дамп сразу на диск - для экономии памяти,
# (если железо на сервере слабое).

# Затем упаковываем файлы сайта вместе с дампом базы в архив.
# При этом исключаем из бэкапа кэш сайта (--exclude=cache/*),
# чтобы уменьшить размер полученного архива.
# Имя архива, для удобства, задаём с временной меткой:
tar czf $SITEBACKUPDIR/mysite.ru-backup-`date +%Y-%m-%d-%H-%M-%S`.tar.gz --exclude=cache/* ./*
chmod 600 $SITEBACKUPDIR/mysite.ru-backup-*.tar.gz

# После завершения резервного копирования
# удаляем дамп базы из директории сайта:
rm -f ./db_backup.sql

cd $SITEBACKUPDIR

# Удаляем все бэкапы, кроме последних NUMBACKUPS: 
x=1
for i in `ls -t`
do
   if [ $x -le $NUMBACKUPS ]
   then
   let x++
   continue
   fi
   rm $i
done

Скрипт делаем исполняемым и закрываем доступ к нему всем кроме владельца:

chmod 700 sitebackup

В завершение помещаем его в подходящую папку, например:

mv sitebackup /usr/bin

И прописываем его в crontab:

30 2 1 * * sitebackup

Таким образом, скрипт будет запускаться в 2:30, первого числа каждого месяца, делать бэкап, и удалять все бэкапы кроме последних NUMBACKUPS (в данном случае - 6).

Выгрузка бэкапов на удалённое хранилище.

В принципе, в этот же скрипт можно было бы добавить ещё несколько строк, чтобы бэкапы выгружались на наше файловое хранилище, например по FTP. Я выгружаю бэкапы на свой домашний роутер под управлением openwrt. Но т.к. роутер у меня смотрит в интернет из-за NAT, с серым IP, то инициировать FTP-соединение приходится не с хостинга, а с роутера. Для этого, под openwrt настроим FTP-клиент и напишем скриптик, который по крону будет забирать бэкапы с сервера.

Под линуксом в качестве FTP-клиента можно использовать консольную утилиту ftp (см. man ftp). Но т.к. в репозитории openwrt её не оказалось, я установил похожую утилиту - cmdftp:

opkg update
opkg install cmdftp

Вызов справки по опциям командной строки:

cmdftp -h

Подключение к FTP-серверу:

cmdftp -n ftp.mysite.ru

Затем вводим логин и пароль. Для справки по ftp-командам, используем команду 'h'.

Наш скрипт будет подключаться по FTP к серверу, проверять содержимое папки с бэкапами и скачивавать бэкапы из неё на локальный диск:

#!/bin/sh

FTP_USER=USER
FTP_PASSWORD=PASSWORD
FTP_BACKUPDIR=/path/to/backups/mysite.ru
LOCAL_BACKUPDIR=/path/to/local/backups/mysite.ru
NUMBACKUPS=12

if [ -d $LOCAL_BACKUPDIR ]
then :
else
   mkdir -p $LOCAL_BACKUPDIR
fi

cmdftp -n ftp.mysite.ru<<EOC
$FTP_USER
$FTP_PASSWORD
cd $FTP_BACKUPDIR
d mysite.ru-backup-*.tar.gz $LOCAL_BACKUPDIR
rename mysite.ru-backup-*.tar.gz -backup- -downloaded-backup-
bye
EOC

cd $LOCAL_BACKUPDIR
x=1
for i in `ls -t`
        do
                if [ $x -le $NUMBACKUPS ]
                then
                let x++
                continue
                fi
                rm $i
        done

Не забываем сделать скрипт исполняемым и, при необходимости, выставить на него нужные права доступа, после чего добавляем его в crontab:

30 4 1 * * sitebackup

Таким образом, скрипт будет в 4:30, первого числа каждого месяца скачивать резервные копии с сервера. Скрипт оставляет в локальном хранилище NUMBACKUPS последних архивов, удаляя все более старые. В данном случае будут храниться 12 последних архивов, то есть - ежемесячные резервные копии за год. По завершению загрузки, скрипт помечает на стороне сервера скачанные архивы, добавляя к имени файла "downloaded". Поэтому скрипт на стороне сервера можно изменить так, чтобы он удалял по маске те файлы, которые помечены скачанными:

cd $SITEBACKUPDIR

# Удаляем все бэкапы, помеченные скачанными:
rm -f mysite.ru-downloaded-backup-*.tar.gz

# Удаляем все бэкапы, кроме последних NUMBACKUPS:
x=1
for i in `ls -t`
do
   if [ $x -le $NUMBACKUPS ]
   then
   let x++
   continue
   fi
   rm $i
done

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

Полезные ссылки:

Программирование на языке командного интерпретатора - shell

Варианты счётчиков в shell скриптах

Блог Про Комп - Bash скрипт для удаления старых файлов

linuxcertif.com - man cmdftp

Теги : shell, скрипт, сайт, бэкап, cron, ftp, резервное копирование

Комментариев: 0

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

Отменить