...

суббота, 5 июля 2014 г.

Десятимиллионный скрипт резервного копирования

image

Это статья-мануал по скрипту резервного копирования, написанному мной. Скрипт написан на python для Linux. Кому интересно прошу под хабракат.


Возможности





  • Создание дифференциальных/полных копий папок

  • Создание дифференциальных/полных копий с файловой системы BTRFS

  • Создание дифференциальных/полных копий LVM томов

  • Создание снапшотов BTRFS

  • Ротирование бэкапов/снапшотов

  • Логгирование хода выполнения резервного копирования

  • Отправка email оповещений

  • Выполнение скриптов до/после резервного копирования


Установка




В /etc/apt/source.list добавить:

deb http://ift.tt/1seJWap precise soft



И выполнить в терминале:

apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 74C7B31B5F4E1715 && apt-get update && apt-get install py4backup



Обновление пакета выполняется командой:

apt-get update && apt-get upgrade py4backup



ИЛИ

Вручную скачать пакет командой:

wget http://ift.tt/1seJWar



и установить его:

dpkg -i ./py4backup_latest.deb



ИЛИ

Для дистрибутивов, отличных от Ubuntu/Debian выполнить:

git clone http://ift.tt/1seJYz7



И скопировать файлы ddd и py4backup в директорию с бинарными файлами (обычно /usr/bin), файл py4backup_lib.py в директорию библиотек python. Также потребуется поставить зависимости вручную. Необходим python 3.x, btrfs-tools (btrfs-progs), lvm2, rsync. В папке examples/ вы найдете примеры конфигурационных файлов. Их необходимо скопировать в /etc/py4backup/

Настройка




После установки необходимо скопировать конфигурационные файлы из примера. Для этого выполните:

mv /etc/py4backup/py4backup.conf.example /etc/py4backup/py4backup.conf
mv /etc/py4backup/jobs.conf.example /etc/py4backup/jobs.conf




И откройте файл py4backup.conf на редактирование текстовым редактором.

Для boolean параметров допустимо использование True/False, yes/no или 1/0.

Отделять параметр от его значения можно символами '=' или ':'.

Каждый параметр должен находится в своей секции. Название секции пишется перед набором параметров в квадратных скобках ('[]')

Порядок следования параметров в секции и секций не важен. Если параметр не указан в конфигурационном файле, то используется стандартное значение.

Пример конфигурационного файла:


[MAIL]
send_mail_reports = True
login = login@test.com
passwd = password
sendto = recipient@test.com
server = mail.test.com
port = 25
tls = True

[DD]
bs = 4M
ddd_bs = 4096
ddd_hash = md5


[LOGGING]
logpath = /var/log/py4backup.log
enable_logging = True
log_with_time = True
traceback = False
command_output = True

[OTHER]
temp_snap_name = py4backup_temp_snap
host_desc = My Description
pathenv = /sbin:/usr/sbin


Рассмотрим параметры подробней:

[MAIL]: здесь определяются параметры отправки уведомлений через email.

send_mail_reports: включает/выключает отправку email отчетов после выполнения задания.

login: логин для входа на smtp сервер.

passwd: пароль для входа на smtp сервер.

sendto: получатели уведомления. Можно вписать несколько адресов через пробел.

server: доменное имя или IP адрес smtp сервера.

port: порт smtp сервера.

tls: включает/выключает использование TLS шифрования.


[DD]: здесь указываются параметры создания резервных копий с помощью программ DD и DDD.

bs: размер блока для программы DD (Используется для создания полных копий LVM томов). Можно указывать размер в байтах, килобайтах (k) и мегабайтах (M). Влияет на скорость создания копии. Оптимальное значение- 32M.

ddd_bs: размер блока для программы DDD (Используется для создания дифференциальных копий LVM томов). Можно указывать размер в байтах. Чем больше размер, тем больше места занимает дифференциальная копия, но тем быстрее она создается. Оптимальное значение- 4096.

ddd_hash: алгоритм хеширования блоков. Возможен выбор между md5, crc32 и None. MD5 сильнее нагружает процессор, чем crc32 и занимает больше места, но в случае использования md5 намного меньше шанс коллизий.

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


[LOGGING]: настройка ведения журнала заданий.

logpath: путь до журнала. Если вы используете не стандартное размещение журнала не забудьте поменять настройки logrotate.

enable_logging: включает/выключает ведение журнала.

log_with_time: включает/выключает добавление к каждой записи журнала даты и времени.

traceback: включает/выключает добавление traceback'ов в лог при ошибках. Полезно при отладке.

command_output: включает/выключает добавление в лог консольного вывода команд. Полезно при отладке.


[OTHER]: настройки, не вошедшие в другие разделы.

temp_snap_name: имя временных снапшотов. Используется при создании копии LVM томов или папок/файлов на файловой системе BTRFS. Рекомендуется не изменять без необходимости.

host_desc: текстовое описание хоста. Значение этого параметра будет добавлено в файл журнала и email отчет.

pathenv: значение этого параметра будет добавлено к переменной $PATH(если пройдет проверку). Если необходимо добавить несколько папок их необходимо разделить двоеточием (':') Например в Ubuntu для создания копий LVM томов при запуске py4backup через cron необходимо добавить в переменную $PATH папку /sbin. В данном случае путь указывается без последнего слеша (‘/’)


Задания




Общие сведения



Список заданий находится в файле /etc/py4backup/jobs.conf

Пример задания:


[mail-diff]
type = file-diff
sopath = server:/opt/
snpath =
dpath = /mnt/backup_dest/
dayexp = 30
prescript = bash /root/script1.sh
postscript = bash /root/script2.sh
include = test test2
exclude = tests*




Где:

[xxx]: уникальное имя задания.

type: тип задания. Подробности см ниже.

sopath: источник резервной копии. В типах file-full, file-diff в качестве источника можно указывать удаленные хосты.

snpath: где создать снапшот. Используется только типами btrfs-full, btrfs-diff и btrfs-snap

dpath: куда сохранять резервную копию. В типах btrfs-full, btrfs-diff, file-full, file-diff в качестве назначения можно указывать удаленные хосты.

dayexp: через сколько дней удалять старые резервные копии. Если установить -1 резервные копии не будут удаляться никогда.

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

postscript: скрипт, выполняющийся после резервного копирования. Остальное аналогично параметру prescript.

include: что включать в резервную копию. Подробности см. в описании типов резервного копирования.

exclude: что исключать из резервной копии. Подробности см. в описании типов резервного копирования.

Внимание! Все пути должны заканчиваться '/'.
Типы резервного копирования



В каждом задании в параметре 'type' указывается тип резервной копии. Этот параметр влияет на схему рез. копирования и на функцию некоторых параметров.

Всего в py4backup есть 7 типов резервного копирования:


  • file-full

  • file-diff

  • btrfs-full

  • btrfs-diff

  • btrfs-snap

  • lvm-full

  • lvm-diff


Рассмотрим их поближе.


file-full



Создает резервную копию используя rsync. Создается резервная копия папки, указанной в sopath включая все папки, примонтированные глубже.

Особенности:

В переменной sopath и dpath можно указывать не только локальные папки, но и удаленные хосты. Например:

sopath = root@192.168.0.1:/home/admin/ или dpath = server:/home/admin. Во втором случае в файле ~/.ssh/config должна быть корректная запись. Используется авторизация по ключам (доп. инфо. см. в wiki вашего дистрибутива).

Нельзя указывать sopath и dpath удаленными хостами одновременно.

Значение указанное в include и exclude передаются rsync в виде опций --include= и --exclude=. Можно указывать несколько значений через пробел.
file-diff



Создает дифференциальную резервную копию от источника (sopath) и последней полной копией, найденной в папке назначения (dpath). Если полная копия не будет найдена выполнение задания завершиться ошибкой.

Список параметров аналогичен типу 'file-full'.
btrfs-full



Данный тип аналогичен типу 'file-full', но перед созданием резервной копии делается снапшот резервируемой директории и копия снимается уже со снапшота.

Для этого типа резервного копирования необходимо указание параметра snpath. В папке, указанной в snpath будет создан временный снапшот исходной папки (sopath). Причем указанный там путь должен находится на одной файловой системе с папкой, указанной в sopath. Обратите внимание, что копируется только содержимое данного subvolume файловой системы. Все примонтированные папки и вложенные subvolume будут проигнорированы. Список остальных параметров аналогичен типу 'file-full'.
btrfs-diff



При этом типе рез. копирования сначала с исходной папки (sopath) снимается снапшот, а затем создается дифференциальная копия от снапшота и последней полной копией, найденной в папке назначения (dpath). Если полная копия не будет найдена выполнение задания завершиться ошибкой.

Так же, как и для типа 'btrfs-full' необходимо, что бы папка для снапшота (snpath) находилась на одной файловой системе с исходной папкой (sopath).

Обратите внимание, что копируется только содержимое данного subvolume файловой системы. Все примонтированные папки и вложенные subvolume будут проигнорированы. Список остальных параметров аналогичен типу 'file-full'
btrfs-snap



Данный тип создает снапшоты от исходной папки, указанной в sopath в папку снапшотов, указанную в snpath.

Для данного типа не работают параметры exclude, include, dpath. Так же, как и для типа 'btrfs-full' необходимо, что бы папка для снапшотов (snpath) находилась на одной файловой системе с исходной папкой (sopath).

Обратите внимание, что копируется только содержимое данного subvolume файловой системы. Все примонтированные папки и вложенные subvolume будут проигнорированы.
lvm-full



Этот тип предназначен для создания полных копий LVM томов. Рассмотрим некоторые особенности данного типа. В параметре sopath указывается путь до Logical Volume Group (VG). Например:

sopath = /dev/main_vg/

По умолчанию скрипт сделает копию всех томов, находящихся в данном VG.

Параметр dpath указывает где сохранять резервную копию. Указывать удаленные хосты в качестве назначения резервной копии нельзя. Для того, что бы сделать копии только нужных томов можно использовать параметры include и exclude.

Параметр exclude указывает какие тома исключить из резервной копии. Кроме того он принимает кодовое слово all, обозначающее, что надо исключить все тома.

Параметр include указывает какие тома нужно включить в резервную копию. Имеет приоритет над exclude. Например:

exclude = all
include = mail root




сделает резервную копию только томов mail и root. А следующий пример сделает копию всех томов, кроме тома mail:

exclude = mail

lvm-diff



И последний (для версии 1.5) тип резервного копирования предназначен для создания дифференциальных копий LVM томов.

Скрипт ищет в папке назначения (dpath) последнюю полную резервную копию и если находит, создает дифференциальную копию между ней и снапшотом текущего состояния. В папке назначения при этом появятся 2 файла *-diff.dd и *-diff.ddm Они ОБА необходимы для восстановления.

Все параметры аналогичны типу lvm-full
Запуск



Запустить требуемые задания на выполнение очень просто.

Необходимо указать ключ –jobs (или -j) и после него указать имена необходимых заданий. Например:

py4backup --jobs backup_data backup_home backup_media

Все указанные задания выполнятся последовательно в порядке их следования в параметре --jobs. Также запуск скрипта возможен через cron, но помните, что переменное окружен cron может отличатся от пользовательского и может потребоваться указать пути до утилит rm, dd, rsync, btrfs, lvcreate, lvremove в переменной pathenv в конфигурационном файле.

Восстановление




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



Написанное ниже относится как к полным, так и дифференциальным резервным копиям, сделанным заданиями типа btrfs-full, btrfs-diff, file-full, file-diff. Восстанавливать резервную копию необходимо rsync с ключами -aAX. Например:

rsync -aAX /mnt/backup/home/2014-06-21-full/ /home/



или

rsync -aAX /mnt/backup/home/2014-06-22-diff/ /home/



В обоих случаях в папке назначения вы получите полную копию данных, готовую к использованию.
Восстановление снапшотов



Снапшоты, создаваемые типом btrfs-snap можно восстанавливать несколькими способами.


  • Как файловый бэкап, скопировав данные rsync (слишком долго и не интересно)

  • Примонтировав снапшот, вместо папки, которую необходимо восстановить. Этот способ мы и рассмотрим ниже.




По умолчанию снапшоты создаются в режиме только для чтения. Соответственно вы не сможете напрямую писать в этот снапшот. Рассмотрим пример.

BTRFS используется в качестве корневой файловой системы. С помощь скрипта создаются снапшоты папки /home и складываются в /snapshots_home. И вот настал день, когда нам необходимо восстановить папку /home из снапшота.

Первым делом необходимо освободить папку /home (переименовать или удалить ее).

Далее мы выбираем нужный нам снапшот (пусть это будет снапшот, за 2014-06-19) и создаем снапшот от него (да, да, снапшот снапшота):

btrfs subvolume snapshot /snapshots_home/2014-06-19 /home



Таким образом мы во первых сделали наши данные доступными для записи и обезопасили их. Даже когда скрипт согласно ротации удалит снапшот от 2014-06-19 наш свежесозданный снапшот будет цел.
Восстановление полных бэкапов LVM



Тут все совсем просто.

Необходимо создать новый LVM том, размера равного или больше резервной копии и скопировать на него резервную копию с помощью dd.

Пример:

dd if=/backups/2014-06-19-old_volume-full of=/dev/main_vg/new_volume bs=32M

Восстановление дифференциальных бэкапов LVM



Для данного восстановления необходимо воспользоваться утилитой ddd, идущей в комплекте с py4backup.

Для восстановления ей необходимо указать опцию –restore, ключ -s с путем до файла БЕЗ РАСШИРЕНИЯ, ключ -r с указанием места восстановления (блочное устройство или файл). ddd запоминает путь до полной резервной копии, но если она была перемещена необходимо вручную указать ей новый путь. Сделать это можно с помощью ключа -f.

Пример:

В папке /backup находятся резервные копии:


root@virtserver / # ls /backup/
2014-06-18-volume-full
2014-06-19-volume-diff.dd
2014-06-19-volume-diff.ddm




И мы хотим восстановить резервную копию за 2014-06-19 на устройство /dev/main_vg/volume Для этого выполним команду:


ddd --restore -s /backup/2014-06-19-volume-diff -r /dev/main_vg/volume




Предположим полная копия была перемещена в папку /backup_old/:


ddd --restore -s /backup/2014-06-19-volume-diff -r /dev/main_vg/volume -f /backup_old/2014-06-18-volume-full




После восстановления ddd выведет список поврежденных блоков с указанием файла, где находится поврежденный блок. Запись full23 указывает на повреждение блока номер 23 в файле полной копии, а запись diff24 на повреждение блока 24 в дифференциальной копии.

Tips & Tricks




Здесь я расскажу о некоторых не очевидных момента и вариантах использования скрипта.

Заключение




Отказ от ответственности: автор скрипта не несет ответственности за действие или бездействие программы, повлекшее потерю или повреждение данных.

В скрипте ЕСТЬ ошибки и я буду благодарен за багрепорты (особенно с traceback’ами и консольным выводом команд).

Данный мануал актуален для версии 1.5.3.

Связаться со мной можно по email, адрес larrabee@nixdi.com или через хабр.

Исходный код на github.

Пакеты в репозитории.

Спасибо за прочтение и буду благодарен за комментарии.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


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

Отправить комментарий