Использование хардлинков (hardlink) для инкрементального бекапа Synology DSM

9f7bf76ea3a24f938876559fd716cf5d.png

Система DSM достаточно удобна и по умолчению в системе установлены модули, которые закрывают 95% потребностей рядового (и не очень) пользователя, что называется «из коробки».
Есть и встроенная система резервного копирования: Backup & Replication. Простая, понятная и надежная. В качестве сетевого места назначения в может использовать либо похожую Synology, либо rsync сервер.
К сожалению эта система не умеет делать инкрементальный бекап. Самый примитивный способ обойти это — настроить отдельный бекап на каждый день недели. Таким образом у нас будет 7 папок с резервными копиями, но очевидный минус — хранение полной копии в каждой папке — объем может получиться таким, что не каждый позволит себе такое хранилище.

Итак — настроим полноценный инкрементальный бекап.
Для начала нам нужен сервер с диском, достаточным для хранения архивов важных данных. Где именно он будет установлен — это зависит от возможностей каждого. Например это может быть виртуальный хостинг или старый системник или виртуальная машина на рабочем компьютере. Про надежность сервера архивации можно спорить, но даже само его наличие — огромный плюс к сохранности ваших персональных данных. Опять же, если в DSM включить уведомления на почту — вы ежедневно будете знать, не было ли ошибок во время резервного копирования и быстро вернете к жизни «упавший» сервер для хранения резервных копий.
Способ, которым сервер будет связываться с Synology (или наоборот) каждый выберет для себя сам — это может VPN, локальная сеть или обычный интернет. Я предпочитаю VPN, но описание настройки подключения выходит за рамки этой статьи (там могут быть нюансы и я опишу это позднее).

Теперь размер диска, на котором будут храниться архивы.
Содержимое домашних хранилок можно уверенно поделить на: Кино, Музыку, Фотки и обычные файлы-документы пользователя.
И если в случае утери данных Кино можно и не сложно скачать заново, Музыку — с большой вероятностью тоже, то Фото и личные файлы уже не восстановишь. Объем таких данных из моего личного опыта не превышает 50-100GB. Например, будем делать ежедневный и еженедельный бекап. Берем по максимуму: 100GB + 100GB – нам понадобится 200GB диск. Думаю? В наше время это редкость, а вот 500GB найти запросто!

Далее я буду рассказывать на примере виртуальной машины, но основная идея применима к любой системе на базе Linux (возможно и FreeBSD).

Итак — ставим Ubuntu server, и активируем на нем SSH и rsync:
Файловая система должна быть с обязательной поддержкой hardlink’ов. Поэтому оставим, предложенную по умолчанию, ext-4.

В принципе, rsync можно запустить и на Windows, но нам нужна поддержка хардлинков, а я не уверен, что rsync умеет корректно работать с виндовыми Junction.

Уточню про модель безопасности на сервере — она будет достаточно простая:
— отдельный пользователь для логина (для Synology)
— ограничение на папку для IP адреса на уровне rsync
— проверка польователей на уровне rsync – отсутствует, хотя может быть легко настроена
— если сервер находится в неблагонадежных сетях на нем рекомендуется включить firewall и ограничить доступ по IP.

Начинаем настройку — создадим папку для хранения архивов и дадим на нее права всем::

$sudo mkdir -p /bakstorage/syno
$sudo chmod 777 /bakstorage/syno

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

$sudo adduser backup

Правим конфиг rsync:

cat /etc/rsyncd.conf
# глобальные параметры:
motd file=/etc/motd
log file=/var/log/rsyncd

# название нашего блока
[syno]

# IP address нашего Synology            
        hosts allow = 192.168.x.x
# коментарий, для удобства
        comment = Syno archive
# Путь к папке, которую мы делаем доступной и где будут храниться архивы
        path = /bakstorage/syno
# Ниже настройки по умолчанию
        use chroot = yes
        lock file = /var/lock/rsyncd
        read only = no
        list = yes
        uid = nobody
        gid = nogroup
        strict modes = yes
        ignore errors = no
        ignore nonreadable = yes
        transfer logging = no
        timeout = 600
        refuse options = checksum dry-run
        dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

и ставим его в автозагрузку:

$sudo update-rc.d rsync defaults

Перезагружаем, проверяем что все поднялось.

Теперь настраиваем архивацию в DSM. Создаем Network Backup Destination:
129bea2106ac4fe091b9323e86295f10.png

Создaем «Data Backup Task», затем создаем задание для ежедневного бекапа. Отмечаем папки, которые необходимо сохранять:
e2f497a185e34e35b9d96bf301a510dd.png

Отмечаем приложения (опционально):
52c00a36b25f48f2b74295f9f7a536b4.png

И самое главное — делаем его ежедневным (последняя опция):
4edb0d24ddde4233a23d1c114b76b2a8.png

Выходим в главное окно приложения, выделяем созданное задание и нажимаем «Backup now» – первое копирование займет много времени. Последующие будут выполняться гораздо быстрее — передаваться будут только новые или измененные файлы.

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

Если оригинальный файл был изменен, а файл назначения является hardlink’ом, то при копировании hardlink “разрывается» и файл назначения заменяется измененной версией.

Опираясь на вышеупомянутое свойство rsync, все что нам надо — после окончания резервного копирования сделать копию папки с архивом командой: cp -al
это создаст полную копию, но все файлы внутри будут являться hardlink’ами, таким образом дополнительное место на диске занято не будет. Ну разве что под дерево каталогов и подкаталогов. Будем называть это созданием снапшота.
К слову: для папки размером в 100GB создание снапшота занимает не больше минуты.

Команду эту мы можем выполнять в любое время, после предполагаемого завершения резервного копирования или, например, за час перед ним.
Таким образом, если резервное копирование запускается в 3:00 и продолжается 6 часов (очень неблагоприятный сценарий — обычно все изменения копируются на порядок быстрее), то снапшот будем делать в 10 утра — чтобы днем мы могли убедиться, что все отработало как надо.

Следующий шаг — хранить N снапшотов и автоматом удалять самые старые. Кстати, при реализации такого удаления обычно удаляют папки, которые старше N дней. Но в случае, если архивация не делалась долгое время (по разным причинам) есть вероятность, что все папки с архивами будут удалены, как устаревшии, а новых — не будет! Поэтому мы учем это.

Ниже скрипты, которые будет делать для нас всю эту работу:

sudo cat /root/rotate_daily.sh

#!/bin/bash
# Выводим дату
echo -n "Started: "
date

# проверяем, что созданный архив, был создан позднее, чем последняя его копия
if [[ /bakstorage/syno/daily -nt /bakstorage/syno/daily_full ]]; then
    # Есть свежий архив - «сдвигаем» старые архивы
    /root/rotate_folders.sh /bakstorage/syno/daily_full 3
         # создаем снапшот свежего архива 
    echo "Copying current backup..."
    cp -al /bakstorage/syno/daily /bakstorage/syno/daily_full
else
         # по какой-то причине свежего архива нет — ничего не делаем 
    echo "No today backup found!"
fi




sudo cat /root/rotate_folders.sh
#!/bin/bash
# ver 1.0

path=$1
hold=$2

if [ -z $2 ]; then

cat <<EOT
Rotate folders script.
Usage: $0 <path_to_folder_prefix>  <folders_to_hold>

Warning! Folders deleted and renamed by mask: path_to_folder_prefix* so please be sure that no any folders in the path
Example: $0 /var/backup/daily 2
The result will be:
  /var/backup/daily   -> /var/backup/daily.1
  /var/backup/daily.1 -> /var/backup/daily.2
  /var/backup/daily.2 -> Deleted
EOT
exit 1
fi

num=$(ls -d $path* | wc -l)
let "num=num-hold"

if [ $num -gt 0 ]; then
    echo "ROTATE_FOLDERS: Found to delete: $num"
    del=$(ls -d $path* | sort | tail -n $num)
    echo "ROTATE_FOLDERS: Deleting folder(s):"
    echo "$del..."
    rm -r $del
else
    echo "ROTATE_FOLDERS: Nothing to delete."
fi

# rename

let "start=$hold-1"

for i in $(seq $start -1 0); do
    let "y=i+1"
    if [ $i -eq 0 ]; then
        echo "ROTATE_FOLDERS: Renaming folders $path to $path.1 ..."
        mv "$path" "$path.1"
    else
        echo "ROTATE_FOLDERS: Renaming folders $path.$i to $path.$y ..."
        mv "$path.$i" "$path.$y"
    fi
done

Не забыть сделать оба скрипта выполняемыми:

chmod 750 /root/rotate_folders.sh
chmod 750 /root/rotate_daily.sh

Добавляем в cron:

$sudo crontab -e

0 10 * * * /root/rotate_daily.sh >>/var/log/rotate_daily.log 2>&1 

Обратите внимание, весь вывод будет записываться в файл: /var/log/rotate_daily.log
Собственно, с ежедневным копированием все!

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

1. Настроить его по аналогии и параллельно с ежедневным. Таким образом у вас будет полностью автономный набор папкок weekly, weekly.1 weekly.2 и т.д. который никак не будет пересекаться с ежедневными папками. Но в этом случае это будет занимать на диске дополнительно столько же места, сколько и ежедневные архивы.

2. Модифицировать скрипт и раз в неделю создавать дополнительный снапшот папки daily в папку weekly, а затем так же переименовывать папку weekly в weekly.1, weekly.2 и т. д. В этом случае дополнительное место будут занимать только измененные файлы, которых обычно очень мало, но если какой-либо файл окажется испорчен, то он будет испорчен во всех папках сразу!

К слову сказать — вышеописанную технику можно применить не только к резервному копированию в Synology DSM, а к любой системе, поддерживающей rsync и hardlink’и.

Удачной настройки!

© Habrahabr.ru