Делаем свою Time Machine для Линукса

в 10:06, , рубрики: backup, linux, time machine, метки: , ,

После интенсивного пользования time machine на маках и пару ситуаций когда она реально пригодилась (были варианты когда пришлось поставить систему из бакапов и варант когда пришлось откатывать назад после проблем), возникла мысль а собственно почему такой удобной системы нет на линуксе. После исследования вопроса и опроса знакомых линуксоидов оказалось что:
1. сделать такую систему можно просто за пару минут на коленках
2. странно, но как-то никто собственно не в курсе что это можно поднять настолько быстро.
3. наша time machine для линукса будет с маджонгом и гейшами.

Как раз был ненужный appletv первого поколения из которого было решено сделать небольшой сервер на hardeded linux для сбора логов и всяких вспомогательных целей. После установки hardened gentoo как раз и возник вопрос как его бы бакапить чтобы весь и сразу диск - чтобы можно было при полном отказе накатить бакап на новый диск или на полностью новый appletv (хм, если потом такой найду конечно), или выборочно востанавливать удалённые или потерянные файлы просто ссылаясь на опеределенную дату.

Как работает time machine? Довольно просто, первый слепок системы просто копируется как файлы со всеми аттрибутами в Backups.backupdb/hostname/YYYY-MM-dd-hhmmss, +делается симлинк Latest указывающий на последний слепок. А уже при втором слепке происходит следующее: сравниваются даты файлов и если файл не поменялся то вместо новой копии файла делается hardlink на файл из предыдущего слепка. Тогда если ничего не поменялось весь новый слепок будет полностью ссылаться на предыдущий. Слепки будут отличатся только новыми/модифицированными/удалёнными файлами. Как результат можно просто удалить любой слепок (каталог типа YYYY-MM-dd-hhmmss) и ничего не поламается. Самая ближайшая ассоциация - умный указатель в c++ например: когда пропадает последняя ссылка на файл (из всех слепков) он и удалится с дисков.

Очень удобная система с точки зрения просмотра предыдущих файлов, их востановления, удаления старых бакапов итд. Вплоть до восстановления всей системы из слепка.

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

rsync имеет чудесную опцию --link-dest которая как раз и делает всю выше описанную логику по сравнению с предыдущими слепками и создания hardlink-ов. Опция -x исключит все примонтированные файловые системы как /proc /sys /dev итд. --delete будет удалять файлы которые пропадут.

Вся time machine будет одним скриптом как:

#!/bin/sh
date=`date "+%Y-%m-%d-%H%M%S"`
SRC=/
DST=/mnt/backup-hdd/Backups.backupdb/atv

rsync -ax
--delete
--link-dest=../Latest
$SRC $DST/Processing-$date
&& cd $DST
&& mv Processing-$date $date
&& rm -f Latest
&& ln -s $date Latest

Ложим в /etc/cron.hourly и вуаля у нас бакапы как в time machine.
Если наша система слетела, мы можем загрузтся со флешки, отформатировать раздел, и запустить тот же rsync в обратную сторону, потом перегрузится или сделать chroot и система опять рабочая.

Еще положим в /etc/cron.daily простой скрипт который будет удалять hourly слепки предыдущий дней оставляя только 24 за последний день, потом удалять daily слепки за предыдущие месяцы итд — как в apple time machine, только выбирайте вашу последовательность.

Хотим заливать бакапы по сети на backup сервер? Тоже пожалуста. Делаем авто авторизацию с ssh ключиками и немого меняем скрипт:

#!/bin/sh
date=`date "+%Y-%m-%d-%H%M%S"`
SRC=/
DST=/mnt/backup-server-hdd/Backups.backupdb/atv

rsync -axz
--delete
--link-dest=../Latest
$SRC backup-user@company.com:$DST/Processing-$date
&& ssh backup-user@company.com
«cd $DST
&& mv Processing-$date $date
&& rm -f Latest»
&& ln -s $date Latest"

Тестируем, 3ГБ система на appletv сравнилась с последним слепком на сервером за минут пять — сервер удалённый — не в локальной сети, соединение было около 1.5MB/s. Мы добавили "-z" для компресии. Неплохо, но если будет расти можно делать не hourly а с большим диапазоном. Надо указать что rsync по сети похоже не передаст «owner:group» файлов — так как будет пользовать пользователя backup-user@… – можно просто сделать дамп всех аттрибутов файлов в текст файл и положить в бакап.

Теперь чего нет у Мак пользователей
1. Гибкая конфигурация с cron.
2. Опция --exclude=PATTERN/--exclude-from=FILE позволяет указать куда более гибкие правила на исключение чем просто указать папки. Например я очень недоволен что time machine бакапит у меня на маке все *.о файлы — компиляция проекта легко раскидывается на пару гигабайт obj файлов, а сами папки проектов я исключать совсем из бакапа не хочу.
3. Легко добавить доп логику чтобы делать локи баз данных если нужно
4. Легко сделать также в дополнению к слепку еще соотв слепок только тех файлов что изменились — легко мониторить потом какие файлы были изменены. Так как hardlink-и то места это много не займёт.
5. Добавьте теперь что сами хотите, у вас всё-таки линукс в руках ;)

Автор: yshurik

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js