ZFS хранит контрольные суммы для каждого блока и поэтому умеет обнаруживать повреждения, которые обычная файловая система пропускает. Команда scrub запускает полную проверку всех выделенных блоков пула: ZFS читает данные, пересчитывает сумму и сравнивает с сохранённой. Если есть избыточность, повреждённый блок восстанавливается автоматически. Разберём, как это работает, как читать отчёт и что делать, когда в статусе появились ошибки.
Как ZFS проверяет целостность
Контрольная сумма хранится не рядом с данными, а в родительском block pointer. Поэтому повреждение самого блока данных не может незаметно изменить его checksum: при чтении ZFS обнаружит несоответствие. По умолчанию используется Fletcher4, для критичных наборов можно включить SHA-256. Суммы проверяются при каждом чтении, а scrub принудительно проходит по всем выделенным блокам, включая давно не читавшиеся.
Защита работает, только если есть откуда восстановить блок: зеркало, RAIDZ, несколько копий через copies или резервная копия. На одиночном диске ZFS честно сообщит о повреждении, но исправить его не сможет. Scrub также не является заменой бэкапу: он не спасает от удаления, шифровальщика или отказа всего пула.
Запуск проверки
Scrub выполняется на смонтированном пуле и не требует остановки сервисов. Сначала полезно посмотреть, нет ли уже известных проблем, затем запустить проверку и наблюдать прогресс.
sudo zpool status -x
sudo zpool scrub tank
sudo zpool status -v tank
sudo zpool scrub -p tank
Флаг -p приостанавливает scrub, -s останавливает. После остановки прогресс может потеряться, поэтому останавливайте только при острой нехватке ресурсов. Повторный запуск на уже проверяющемся пуле не создаст второй процесс: ZFS сообщит, что scrub уже идёт.
Прогресс отображается в колонке scan. Для больших пулов проверка может идти часами и сутками; это нормально. На время scrub растёт нагрузка на диски, поэтому в продакшене его обычно планируют на ночь или окно обслуживания.
Чтение отчёта zpool status
В таблице перечислены диски и счётчики ошибок чтения, записи и контрольных сумм. Ненулевой CKSUM означает, что данные не совпали с checksum. Если пул избыточен, ZFS попытается прочитать исправную копию и увеличит счётчик исправленных ошибок.
sudo zpool status -v tank
sudo zpool events -v
sudo zdb -C tank
sudo smartctl -a /dev/sdb
zpool status -v показывает пути повреждённых файлов, если они известны. zpool events даёт журнал событий, zdb -C — конфигурацию пула, а smartctl — здоровье конкретного накопителя. Счётчик CKSUM на одном диске при исправных данных на других часто указывает на кабель, контроллер, питание или оперативную память, а не только на сам диск.
Если CKSUM растёт сразу на всех дисках, проверьте dmesg на ошибки ATA и протестируйте RAM. Общая причина повреждений опаснее единичного сбойного носителя: замена диска не поможет, пока не устранён источник.
Полезно проверить настройки:
zfs get checksum,copies tank/data
zpool get ashift tank
zpool list -v tank
zfs get compressratio tank/data
Если copies=2, ZFS хранит две копии блоков, но это не заменяет зеркало: копии могут оказаться на одном диске. ashift влияет на выравнивание, а не на целостность; менять его после создания пула нельзя.
Что делать при ошибках
Сначала не очищайте счётчики. Определите, какой диск или компонент виноват, проверьте SMART, кабели, backplane и память. Если пул имеет избыточность, запустите scrub повторно: при чтении ZFS попробует восстановить блоки с исправных копий. После успешного восстановления можно очистить ошибки командой zpool clear, но только когда причина устранена.
sudo zpool offline tank /dev/sdb
sudo zpool replace tank /dev/sdb /dev/sdd
sudo zpool status -v tank
sudo zpool clear tank
Замена диска в зеркале или RAIDZ запускает resilver. Он перестраивает данные на новый носитель и также может выявить ошибки на оставшихся дисках, поэтому важно иметь свежий бэкап. Для одиночного пула без избыточности единственный путь — восстановить файлы из резервной копии; zpool clear лишь скрывает счётчики и не лечит данные.
Если ошибки появляются на разных дисках одновременно, подозревайте общую причину: контроллер, кабель, блок питания или RAM. Проверка памяти и замена подозрительного компонента важнее, чем повторные scrub.
Как планировать scrub
Домашнему пулу достаточно ежемесячной проверки, архиву с редкой записью — раз в квартал. Слишком частый scrub на SSD создаёт лишнее чтение, но современные накопители обычно справляются. Важны регулярность и контроль результата. Для круглосуточного пула выбирайте окно с минимальной нагрузкой и предупреждайте пользователей.
# /etc/systemd/system/zfs-scrub-tank.service
[Unit]
Description=ZFS scrub tank
[Service]
Type=oneshot
ExecStart=/sbin/zpool scrub tank
# /etc/systemd/system/zfs-scrub-tank.timer
[Unit]
Description=Monthly ZFS scrub
[Timer]
OnCalendar=monthly
Persistent=true
[Install]
WantedBy=timers.target
Создайте оба файла в /etc/systemd/system/, затем включите таймер. Persistent=true догонит пропущенный запуск после выключения. Проверьте путь к zpool и не дублируйте готовые шаблоны из zfsutils-linux.
sudo systemctl daemon-reload
sudo systemctl enable --now zfs-scrub-tank.timer
systemctl list-timers 'zfs*'
journalctl -u zfs-scrub-tank.service --since '1 month ago'
- ежемесячно — домашний пул;
- раз в квартал — архив с редкой записью;
- результат проверки — в мониторинг.
Нюансы производительности
Scrub читает все выделенные блоки, поэтому конкурирует с рабочей нагрузкой за IOPS и пропускную способность. На HDD это заметно сильнее, чем на SSD. Приостановка помогает временно снять нагрузку, но проверку всё равно нужно завершить. Не запускайте scrub одновременно с resilver и тяжёлой записью, если сервис чувствителен к задержкам.
Сжатые блоки проверяются в сжатом виде. Для шифрованных наборов scrub проверяет и служебные структуры, поэтому повреждение метаданных обнаруживается до расшифровки. На SSD полная проверка добавляет чтение, но при ежемесячном запуске обычно не критична.
Дедупликация увеличивает потребление памяти и не делает scrub ненужным. Scrub не проверяет свободное пространство и не находит повреждения в невыделенных блоках — это нормально, потому что там нет данных.
Итог
Scrub — штатный способ убедиться, что ZFS читает именно те данные, которые записала, и что избыточность действительно работает. Запускайте его регулярно, читайте zpool status -v, не очищайте ошибки до выяснения причины и держите независимый бэкап. Если пул без избыточности, scrub поможет вовремя узнать о проблеме, но восстановить данные придётся из копии. Здоровая практика проста: ежемесячная проверка, мониторинг SMART и понятный план замены диска.