Снапшоты ZFS спасают от неаккуратного удаления файлов и от сбойного обновления, но не спасают от смерти носителя: если диск умер вместе с машиной, локальных копий больше нет. В домашней лаборатории логична схема из двух узлов: основной мини-ПК с пулом и старая машина с одним диском в роли приёмника. Настройка репликации сводится к паре команд и одному скрипту по расписанию — пройдём по шагам.

Создание пула

Имена дисков в /dev/sdX недолговечны и меняются после перезагрузки, поэтому с самого начала работайте с символьными ссылками по идентификаторам:

ls -l /dev/disk/by-id/
sudo zpool create -o ashift=12 -O compression=zstd -O atime=off -O mountpoint=/tank tank mirror /dev/disk/by-id/ata-DISK1 /dev/disk/by-id/ata-DISK2
sudo zpool status tank
sudo zfs list

Зеркало из двух дисков — разумный минимум для домашних данных. Параметр ashift=12 соответствует секторам 4 КБ современных накопителей, сжатие zstd почти не грузит процессор, а отключённый atime избавляет от лишних записей при каждом чтении. Отдельным датасетом создайте каталог с данными, чтобы не монтировать файлы прямо в корне пула:

sudo zfs create tank/data
sudo zfs set sharenfs=on tank/data

Снапшоты

Снапшот — мгновенный снимок состояния датасета, который занимает место только под изменённые блоки:

sudo zfs snapshot tank/data@clean
sudo zfs list -t snapshot -o name,creation,used tank/data

Для дерева датасетов снимайте рекурсивно: zfs snapshot -r tank/data@before-update. Откат выполняется через rollback, но учтите: он удаляет все снапшоты, сделанные после целевого. Если старая версия нужна только для сравнения, надёжнее сделать клон командой zfs clone и скопировать нужные файлы руками — так ничего не потеряется. Практичные имена для регулярных снимков:

  • @clean — точка отсчёта перед ручным изменением конфигурации или обновлением;
  • @before-update — снимок непосредственно перед установкой пакетов;
  • @daily-2026-11-05 — автоматический снимок от скрипта по расписанию;
  • @last-sent — последний снимок, ушедший на резервную машину.

Первый полный перенос

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

ssh backup "zpool list"
sudo zfs send tank/data@clean | ssh backup "zfs recv -F backup/tank/data"
ssh backup "zfs list backup/tank/data"

Полный поток содержит все данные датасета, поэтому в первый раз он самый тяжёлый и занимает время пропорционально объёму. На приёмнике данные попадают в пул backup — держите резервный пул отдельным, чтобы не смешивать его с системными датасетами. Флаг -F разрешает перезапись приёмной части, что необходимо для повторных приёмов поверх существующих данных.

Инкрементальная репликация

Дальше переносятся только изменённые блоки между двумя снапшотами:

sudo zfs send -c -i tank/data@clean tank/data@next | ssh backup "zfs recv -F backup/tank/data"

Ключ -c включает сжатие потока на лету, а -i задаёт отправку инкремента от предыдущего снапшота. Для дерева датасетов добавляют -R, тогда команда переносит структуру и свойства целиком. Ограничение одно: инкремент требует, чтобы родительский снапшот существовал на приёмнике. Если вы удалили его скриптом чистки, перенос упадёт с ошибкой, и придётся заново делать полный send.

Если перенос прервался

Большой поток легко оборвать: пропало соединение по SSH или закончилось место на приёмнике. Решается возобновляемой отправкой: приёмник сохраняет состояние, а источник докачивает остаток по токену.

sudo zfs send -c -i tank/data@clean tank/data@next | ssh backup "sudo zfs recv -s -F backup/tank/data"
ssh backup "zfs get -H -o value receive_resume_token backup/tank/data"
sudo zfs send -t ТОКЕН_ИЗ_ВЫВОДА

Приём с флагом -s записывает токен продолжения в свойство receive_resume_token. Выведите это значение, подставьте в send -t — и останется докачать только оставшуюся часть потока. На медленном канале между комнатами эта функция экономит часы и нервы.

Доступ по SSH только для репликации

Скрипту нужен негоняемый доступ к приёмнику. Заведите отдельную пару ключей без парольной фразы и запишите публичный ключ в файл /root/.ssh/authorized_keys на резервной машине:

ssh-keygen -t ed25519 -f ~/.ssh/zfs_repl -N ""
# строка в authorized_keys приёмной машины:
restrict,from="192.168.1.10" ssh-ed25519 AAAA... zfs-repl

Ключевое слово restrict снимает все привилегии ключа, оставляя перенаправление потока, а аргумент from привязывает его к адресу основной машины. Даже утечка ключа не даст с него залогиниться в интерактивную сессию.

Автоматизация по расписанию

Ручные команды хороши для проверки, но репликация должна идти сама. Пример скрипта, который помнит имя последнего отправленного снапшота:

#!/bin/sh
set -e
LAST=$(sudo zfs list -H -t snapshot -s creation -o name tank/data | tail -1)
PREV=$(cat /var/lib/zfs-repl/last 2> /dev/null || true)
if [ -n "$PREV" ] && sudo zfs list -H -t snapshot "$PREV" > /dev/null 2>&1; then
  sudo zfs send -c -i "$PREV" "$LAST" | ssh backup "zfs recv -F backup/tank/data"
else
  sudo zfs send "$LAST" | ssh backup "zfs recv -F backup/tank/data"
fi
echo "$LAST" > /var/lib/zfs-repl/last

Логика проста: если предыдущий снапшот ещё существует на источнике — отправляем инкремент, иначе — полный поток. Повесьте скрипт на systemd-таймер или cron, например раз в сутки, и заведите отдельную SSH-ключевую парь только для репликации, чтобы её нельзя было использовать для интерактивного входа.

Снапшоты на приёмнике и скраб

Принятые снапшоты никуда не деваются и растут со временем. Посмотрите на них и приберитесь:

ssh backup "zfs list -t snapshot -r backup/tank/data"
ssh backup "sudo zfs destroy backup/tank/data@old"
sudo zpool scrub tank
ssh backup "sudo zpool scrub backup"

Скраб сверяет контрольные суммы всех блоков и находит деградацию до того, как о ней сообщат пользователи. Раз в месяц на источнике и раз в квартал на приёмнике — достаточный ритм для домашней лаборатории. Следите и за местом: zpool list показывает используемый объём, а на приёмнике он растёт ровно настолько, насколько отстаёт резервная копия от источника. Результат проверяется командой zpool status: строка об окончании скраба без ошибок означает, что данные целы на обоих узлах.

Итог

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

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте