image

КДПВ, ради хайпа, а не флейма.

Моя попытка облегчить муки в процессе резервного копирования хотя бы на чуть-чуть. Какие требования были мной выдвинуты и как я их реализовал.

Скажу сразу, статья не про системы контроля версий. Кто из вас кладет чертежи из САПРа в Git? А стомегабайтные графические файлы? Ежедневно? И не про облачные хранилища. Статья про реализацию конкретной потребности, которая была озвучена не раз знакомыми и коллегами, пользующихся обычной MS Windows, создающих что-то дома или в офисе.

Однажды осознаешь, что не стоило неделю назад удалять страницу в чертеже, или объединять слои в скетче. Допустим, бэкапы делались, даже инкрементальные. В этот момент меньше всего хочется разбираться, как достать файлы из контейнера, гуглить ключи командной строки и все это самое. Хочется самого простого — любым файловым менеджером найти свежайшую версию файла, или недельной давности, лучше по имени, а не хешу содержимого. Не тот файл? Может нужен двухнедельной давности?

Так появилась моя разработка. Назвал ее BURO. Никак не расшифровывается.

Вдохновителем была утилита rdiff-backup, но у нее был «фатальный недостаток». Написана она на python и хранит данные в текстовых пожатых файлах. Ждать по 20 минут, когда она отработает в конце рабочего дня, или готовясь отойти ко сну, для меня было не приемлемо. Не может оперировать очень длинными именами. Даже страшно подумать, как мне из резерва «отмотать» нужный файл на n правок/дней назад.

Для примера, покажу как сделать резервную копию папки:

buro --backup --srcdir="путь к резервируемой папке" --dstdir="куда будем резервировать"

В папке, указанной как dstdir, будет создан файл buro.db и папка mirror, которая будет полной копией папки srcdir. В следующий раз, когда мы запустим ту же самую команду, в папке dstdir будет создана подпапка, названная меткой времени запуска резервирования, в которую будут перемещены модифицированные или удаленные файлы, по сравнению с предыдущим запуском. Выглядит это примерно так:

<2017-06-14T00-01-34.771>
??<Отчеты о практике>
????Отчет1.doc
<2017-06-15T00-57-35.858>
??Список покупок.xls
<mirror>
??<Отчеты о практике>
????Отчет1.doc
????Отчет2.doc
??<Для мамы>
????Vivaldi.mp3
??Список покупок.xls
buro.db

Как видно, сохранилась возможность достать файловым менеджером любой файл и его предыдущие версии. Имена и пути сохранились. Ура!

Восстанавливаются файлы из резерва командой:

buro --restore --srcdir="откуда восстанавливаем" --dstdir="куда восстанавливаем"

Тут все просто. Если нужно состояние папки на определенную дату, то добавляем аргумент —timestamp и указываем дату в формате «YYYY-MM-DD HH:mm:SS.SSS», например:

buro --restore --srcdir="z:\backup" --dstdir="d:\documents" --timestamp=”2017-06-15 00:00:00.000”

Точно время состояния бэкапа указывать не обязательно, можно любое промежуточное.

Инкременты стали занимать много места? Руками удалять не нужно, есть команда purge. Пример:

buro --purge --srcdir="где лежит бэкап" --older="P30D"

Аргументом older указываем конкретную дату, либо период времени в формате ISO 8601 (P1Y2M3DT4H5M6S, в примере выше выбран период 30 дней).

Но ведь даже та самая Visual Studio каждый раз генерирует служебных файлов на многие мегабайты. Место не бесплатное. Настраивать маски файлов и папки для исключения? Пффф… Есть опция сжатия файлов! Команде --backup добавляем аргумент --compress и каждый файл будет преобразован в архив bzip2. К имени файлов также будет добавлено расширение ".bz2" Степень сжатия задается числом от 1 до 9 (по-умолчанию 5). Пример:

buro --backup --srcdir="d:\myprojects" --dstdir="g:\backup" --compress=9

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

Мой типичный сценарий бэкапа, под который и разрабатывалось Buro, это сохранение на съемный носитель или сетевой диск. Данные переносятся в слабо контролируемую среду, секретность не помешает. Шифрование съемных носителей, и тем более сетевых дисков, это всегда немножко грустная тема, особенно если с файлами планируется продолжить работу в другом месте. Но и тут есть решение! Встроенное шифрование. К команде --backup добавляется опция --password. К имени файлов добавляется расширение ".encrypted" Можно одновременно использовать сжатие и шифрование, расширение все равно будет ".encrypted"

Предположим, на предприятии неадекватная СБ, у которой могут возникнуть вопросы к происхождению файла «Зарплатная ведомость руководства.xls.encrypted». Для этого реализована опция шифрования имен --encodenames.

Пример. Каталог с файлами

<.github>
<doc>
<fmt>
<support>
<test>
.gitignore
.travis.yml
Android.mk
ChangeLog.rst
CMakeLists.txt
CONTRIBUTING.rst
LICENSE.rst
README.rst

Превращается в:
<3kOFykh>
<aqFkiIL7WrQu>
<fInOJigKGsSu>
<QCvcAkh>
<WmT4cT0A>
Au!U33x!41SS(8Ir
BuN0kVhe85aPkQh2$
fS1twqYhBCWCagGr
IKNW$LFo3$x9Mgb!rQd
nzSFA6G3RGfKkFA~XaXDZ
pWWMxno894zDuu0L!s3WY
rHtwmdKLrYxkWN~)NtKCuxH4Q
UiJ~)YM0zu01O8g52x~iAPIk

Если кому-то интересны технические детали реализации шифрования:

При использовании опции защиты паролем файл «buro.db» также шифруется. Движок БД — Berkeley DB, шифрует данные алгоритмом AES CBC 128bit, ключ получается из SHA1(пароль + соль). Моя утилита пропускает пароль пользователя через функцию Argon2, получает на выходе 256 бит данных, преобразует в текстовую строку, которая служит паролем к БД. Для шифрования файлов и имен используется алгоритм ChaCha20. Ключи генерируются случайно и сохраняются БД. Я поленился для каждого файла заводить свой ключ, пользуюсь одним. Чтобы нельзя было наложить друг на друга разные версии одного файла, для каждого генерируется свой NONCE, записываю его как первые 8 байт шифрованного файла. Имена файлов перед шифрованием сжимаются простым LZ-подобным алгоритмом, чтобы было труднее угадать длину исходного имени. Поправьте меня, если в чем-то ошибся.

Скучные подробности:

  • Информационные сообщения выводятся в stdout, сообщения об ошибках в stderr;
  • Чтобы видеть подробную информацию, что куда копируется и перемещается, используйте опцию --verbose;
  • Чтобы добавить к сообщениям метку времени, используйте опцию --printtimestamp. Чтобы отобразить уровень логгирования, используйте --printloglevel;

Не стал добавлять контроль целостности данных контрольной суммой, ИМХО в процессе передачи данных и так идет контроль на многих уровнях. Если очень хочется, используйте опцию сжатия, там контроль есть, я так и делаю.

Для заинтересовавшихся ссылка на исходные коды и бинарники.

p.s. В процессе разработки Buro у меня скончался SSD. Какая ирония.
Поделиться с друзьями
-->

Комментарии (17)


  1. 4ebriking
    19.06.2017 21:30
    +7

    Берём (покупаем!) WinRar. изучаем файл ключей. он небольшой и русскоязычный (для толпы мужиков «за 60» — это важно — они могут быть доки в сопромате и какой-нибудь гидродинамике, но IТ-английский для них взаправду боль).
    прописываем cmd-файл что-то вида
    winrar a @файл-список куда
    ключиками ему пишем «архивировать с полными путями», «открытые для записи», «добавлять к имени архива дату», и, например, «с датой изменения не старше недели»
    и запускаем хоть раз в час и/или по расписанию.
    лучше ещё задать простой пароль типа 111 — просто что бы антивирусы не парсили каждый раз.
    Далёкому от софта технарю это дело освоить и наладить как надо со всеми подвохами хитрыми — день, ещё неделю в голове подержать. что бы разные варианты предусмотреть.
    (напр список файлов с именем (датой) архива в отдельный текстовый файл дописывать — что бы потом не рыться по архивам где оно лежит)
    Для конструкторов и дизайнеров — самое оно — всегда можно выудить за любую дату промежуточные файлы.
    Хотя лучше всё же все простые (офисные) и «тяжелые» по разным архивам распихивать. лучше даже каждый со своим расписанием.
    Решал в точности эту задачу силами технарей без админа — но мне важнее было физически бэкап с территории надёжно вынести ввиду кучи разных обстоятельств.


    1. sergarcada
      20.06.2017 08:35
      +2

      Большинство бесплатных бекап-утилит как раз и работает по этому принципу. Берем хрен знает что, копируем хрен знает куда, и ищем хрен знает как. В реальности все выглядит более грустно.
      1. Ошибки доступности источника (источников) — ошибки на харде, недоступен сетевой ресурс, недопустимая длина в имени и.т.д.
      2. Ошибки получателя — добавим внезапно закончившееся место
      3. Непонятно как искать, как хранить заданное n копий файла, как рассчитать требуемое место для следующего бекапа.

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


      1. tandzan
        20.06.2017 15:20

        Сразу по всем 3 пунктам, я делал так — вывод в stderr перенаправляется в файл, если утилита вернула что-то отличное от 0, то содержимое рассылается по почте ответственным, сама ОС контролирует успешность операций копирования и т.п.
        Off: На самом деле кипишь не об этом. Офисному работнику системы контроля версий не под силу. Даже от конструкторов слышал, что две кнопки "ОК" и "Отмена" — это слишком сложно. (Поскипал много эмоционального текста)


        1. sergarcada
          21.06.2017 09:02

          Офисному работнику, имхо, об этом знать вообще не обязательно. Так что две кнопки — это многовато ;) Есть же планировщик.
          Но и я немного о другом. Вот стоит любая система бекапа, в хранилище копируют бекапы три десятка пользователей и в один момент места на дисках не хватает. Если мы имеем распределенную систему с агентами копирования — то о такой ситуации мы узнаем только по факту. Если же мы делаем бекапы общедоступных ресурсов силами сервера — можно посчитать заранее, сколько потребуется места и предупредить об этом.

          Пример: в 17.00 все ушли, в 19.00 запускается бекап по расписанию. А дальше два варианта: если место посчитано заранее — о нехватке мы узнаем этим же вечером. Если нет — то только по окончании копирования, не исключено что завтра утром.

          Другой пример: Бухгалтерии не требуются копии документов, поскольку часто они все связаны между собой. Проще откатить все данные на сутки. Система контроля версий им не нужна. А диспетчер вносит изменения в оперативные схемы и ему может портебоваться несколько версий одного документа. Система бекапа этого не предусматривает — копаем кучу файлов ручками. Предусматривает — можем заранее сказать в какие дни были сделаны копии.

          Алерты тоже хорошо, что шлются, но есть же важность у каждого. Где-то не сохранился один файл и тьфу на него, а где-то возникла ошибка запуска. В моем случае все это попадает (должно попадать) в zabbix, который уже сам сортирует, стоит меня будить ночью или доживет до утра.

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


  1. si1v3r
    19.06.2017 22:04
    -3

    (покупаем!) WinRar

    Рошаль перелогиньтесь.


  1. vesper-bot
    20.06.2017 09:17

    Поздравляю, вы изобрели историю файлов Windows. :)


    1. tandzan
      21.06.2017 00:30

      Не списывайте Windows XP :)


  1. varnav
    20.06.2017 11:51

    Я пользуюсь Duply под nix и Duplicati под винду.


  1. whitedruid
    20.06.2017 13:32
    +1

    Хотел бы поделиться следующим решением, которое внедрил лет 5 назад для компании, где много людей с Solidworks работает и AutoCAD. Не изящное, конечно, но работает (прошу не минусить) :)
    Итак, сервер Linux и общий каталог, подключенный по SMB. Структура \\backup\$username\$uniq_id{1,2,3...99} — $uniq_id — это идентификатор 32 символьный. Пользователь в любой каталог копирует нужное содержимое + в каталоге $uniq_id\td создаёт текстовый файл с определенным содержимым типа «key=value». Там значения сколько хранить, простое описание. Ну а дальше — по ночам осуществляется обработка с помощью sh-скрипта, что называется «парсятся файлы» :) — создаётся запись в СУБД, а сам архив переноситься в более надёжную (и более медленную) систему хранения. Утром приходит на почту пользователю письмо с описанием — какие задания были выполнены, сколько срок хранения и URL — что нужно вбить в браузере для восстановления. Когда нужно восстановить: достаточно переход по URL осуществить и, в зависимости от нагрузки на сервера, файл будет скопирован (с помощью rsync, который в фоне запускается раз в несколько минут и копирует из списка все, что указано) в \\backup\restore\$uniq_id


  1. danSamara
    20.06.2017 14:04

    Хранение копий бинарных файлов быстро выжрет место или история будет короткой.
    Важная часть систем бэкапирования — безопасная и быстрая передача файлов на другой сервер — не решена.
    Мультиплатформенность отсутствует, как я понимаю, а это минус — на линуксах легче найти дешёвые стораджи.
    Кстати как настроить распространенную схему бэкапов: «11 за прошлые месяцы + 3 за прошлые недели + 6 за прошлые дни + 23 за прошлые часы»?

    Я бы рекомендовал присмотреться к Borg


    1. tandzan
      20.06.2017 14:54

      Видимо многие не поняли основной посыл статьи. Смысл — пользователю в конце рабочего дня кликнуть по скрипту и быть свободным. Не проблема вывести на экран окно с предупреждением в случае ошибок в процессе. Зачем пользователю линукс тут, не очень понятно. Если он в 1С данные забивает, то статья не про него.
      Что может быть быстрее операции копирования файла? Хард вынуть?


      1. Scorry
        21.06.2017 16:30

        Вы изобрели велосипед, но по непонятной причине. Вся описанная функциональность давно уже доступна в разных программах разной функциональной наполненности и разной, чаще всего нулевой, цены. Больше всего их на *nix-платформах, и программы оттуда великолепно работают с виндовыми данными и имеют вполне понятные и интуитивные веб-интерфейсы. Вам дополнительно и не зря указали на необходимость использования сервера для создания резервных копий — а вы не поняли, зачем. А сервер нужен, чтобы с машины, которая оперирует данными, не было доступа к уже имеющимся резервным копиям. Резервное копирование в сетевую папку — считайте, что это отсутствие резервной копии вообще.


    1. darthslider
      20.06.2017 17:24

      Тут дедупликация может сильно помочь на самом деле. Мы как раз бинарные бекапы каждодневные для одной хитрой софтины снимаем, очень эффективно получается.


  1. Hint
    20.06.2017 15:03
    +1

    Уже почти 8 лет назад тоже писал программу для непрерывного резервного копирования. Статья на хабре: https://habrahabr.ru/post/75606/
    Довольно долго пользовался ей и радовался жизни. А потом появилась история файлов Windows, которая полностью покрыла все потребности, и мой велосипед оказался не нужен. Теперь всё автоматически копируется на NAS в зашифрованную папку. А самое удобное, что управление интегрировано в обычный проводник. Плюс разные стратегии удаления старых версий (ограничение по времени, по размеру и пр.).


  1. alcohollica
    21.06.2017 00:26

    Shadow Copy вроде бы была ещё в Win 2003…


  1. Kerman
    21.06.2017 00:28
    +2

    Хардкор, но труъ:
    unix + samba + zfs.
    Ежедневные снапшоты (да хоть ежеминутные) не нагружают фс с её парадигмой копи-он-райт.
    В случае чего, снапшот монтируется отдельной шарой, не мешая никому.


    1. sergarcada
      21.06.2017 09:19
      +1

      Это уже больше относится к сетевому хранилищу, чем системе резервного копирования. Можно использовать например Nas4Free — там вам и zfs, и программный raid, и сетевая корзина. Для небольшого надежного хранилища вполне достаточно.