ZFS для системы хранения: команды и практические приёмы администрирования в 2026 | AdminWiki

ZFS для системы хранения: команды и практические приёмы администрирования в 2026

11 сентября 2026 14 мин. чтения
Содержание статьи

Базовый набор ZFS-команд для повседневной работы

Пять команд закрывают большую часть ежедневных задач администратора ZFS: zpool create, zpool status, zfs create, zfs set, zfs list. Добавьте к ним zpool iostat, smartctl и zfs send, и вы получите полный рабочий набор для пула на десятки терабайт.

Синтаксис ниже проверен на OpenZFS 2.3 и новее в Ubuntu 24.04, RHEL 10, TrueNAS SCALE и FreeBSD 14.x. Все операции с пулами выполняются от root или через sudo: делегирование прав командой zfs allow работает на уровне датасетов, а создавать, экспортировать и уничтожать пулы непривилегированный пользователь не может.

ЗадачаКоманда
Создать зеркалоzpool create tank mirror disk1 disk2
Создать RAIDZ2zpool create -o ashift=12 tank raidz2 disk1 ... disk6
Создать датасетzfs create tank/data
Включить сжатиеzfs set compression=lz4 tank/data
Ограничить объёмzfs set quota=500G tank/data
Проверить пулzpool status -v
Проверить местоzfs list -o name,used,avail,refer
Проверить нагрузкуzpool iostat -v 5
Сделать снапшотzfs snapshot tank/data@2026-09-11
Отправить на второй серверzfs send -i tank/data@base tank/data@new | ssh backup zfs receive backup/data
Проверить дискsmartctl -a /dev/sda

Имена устройств вида /dev/sdX меняются после перезагрузки, переподключения кабеля или обновления ядра. Собирайте пулы на /dev/disk/by-id/...: тогда zpool status всегда покажет тот физический диск, который вы имели в виду.

Практическое решение: TimeWeb

Создание пула: zpool create

# зеркало: минимум два диска, переживает отказ одного
zpool create tank mirror /dev/disk/by-id/ata-DISK-A /dev/disk/by-id/ata-DISK-B

# RAIDZ1: минимум три диска, переживает отказ одного
zpool create -o ashift=12 tank raidz1 /dev/disk/by-id/ata-DISK-A /dev/disk/by-id/ata-DISK-B /dev/disk/by-id/ata-DISK-C

# RAIDZ2: минимум четыре диска, переживает отказ двух
zpool create -o ashift=12 -O compression=lz4 tank raidz2 /dev/disk/by-id/ata-DISK-A /dev/disk/by-id/ata-DISK-B /dev/disk/by-id/ata-DISK-C /dev/disk/by-id/ata-DISK-D

# страйп: без избыточности, только под временные данные
zpool create scratch /dev/disk/by-id/ata-DISK-A /dev/disk/by-id/ata-DISK-B

mirror даёт лучшую скорость на случайных операциях и быстрое восстановление, но платите вы половиной ёмкости. RAIDZ1 разумен на четырёх-пяти дисках, RAIDZ2 и RAIDZ3 берите для массивов от шести дисков и для накопителей объёмом от 8 ТБ, когда resilver растягивается на сутки. Страйп из одиночных vdev отказывает целиком при потере любого диска.

Параметр ashift=12 выставляйте для всех современных накопителей: сектор 512e и 4Kn требует выравнивания по 4 КБ. Пул с ashift=9 выполняет read-modify-write для каждого блока меньше 4 КБ, и скорость случайной записи падает в разы. Изменить ashift после создания пула нельзя, только пересобрать массив.

Флаг -f (force) применяйте осознанно: он перезапишет метки на дисках, которые входят в другой пул или содержат файловую систему. Сравнение ZFS-зеркал с программным RAID на mdadm и LVM приведено в материале о программных RAID-массивах на Linux в 2026 году.

Управление датасетами: zfs create и zfs set

zfs create tank/data
zfs create -o mountpoint=/srv/app -o compression=zstd tank/app

zfs set compression=lz4 tank/data
zfs set recordsize=1M tank/data
zfs set quota=500G tank/data
zfs set atime=off tank/data
zfs set xattr=sa tank/data

zfs get compression,recordsize,quota,atime tank/data
zfs get -r compression tank

Датасеты наследуют свойства от родителя: общие параметры задают один раз на корне пула, частные переопределяют на конкретном датасете. compression=lz4 включён по умолчанию в OpenZFS 2.x, но после апгрейда пула со старых версий значение легко проверить через zfs get. Для смешанных данных lz4 выигрывает почти всегда, zstd даёт лучшее сжатие ценой нагрузки на CPU.

recordsize влияет только на новые блоки. Датасет под PostgreSQL держите на recordsize=16K, под виртуальные машины, медиафайлы и бэкапы ставьте 1M. Смена recordsize на живом датасете не требует размонтирования, но уже записанные данные перейдут на новый размер только после перезаписи. Свойство atime=off убирает лишние операции записи при чтении и заметно снижает износ SSD.

Просмотр состояния: zpool status и zfs list

zpool status -v
zfs list
zfs list -o name,used,avail,refer,mountpoint
zfs list -t snapshot
zpool iostat -v 5

zpool status отвечает на вопрос, жив ли массив. zfs list показывает, куда ушло место. zpool iostat выводит текущую нагрузку в операциях и задержке. Привычка открывать zpool status после любой операции с дисками экономит часы разбирательств.

Создание и удаление пулов не имеют корзины. zpool destroy tank и zfs destroy -r tank/data уничтожают данные сразу, если на другом пуле нет снапшотов или реплики на втором сервере. План безопасного вывода пула из эксплуатации описан в статье о том, как безопасно удалить пул ZFS и подготовить диски к повторному использованию.

Диагностика состояния пулов и дисков

Порядок проверки при первых признаках проблемы: zpool status, затем smartctl по подозрительным дискам, затем dmesg. Такой порядок отсекает ложные тревоги и находит причину за несколько минут.

Чтение zpool status: что означают state, scan и errors

  pool: tank
 state: DEGRADED
status: One or more devices could not be used because the label is missing
        or invalid. Sufficient replicas exist for the pool to continue
        functioning in a degraded state.
action: Replace the device using 'zpool replace'.

  scan: scrub repaired 0B in 04:12:33 with 0 errors on Sun Sep  6 03:12:44 2026

config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            sda     ONLINE       0     0     0
            sdb     FAULTED      3     0     0  too many errors

errors: No known data errors

state показывает состояние всего пула: ONLINE, DEGRADED, FAULTED, UNAVAIL, SUSPENDED. DEGRADED означает потерю избыточности: один или несколько vdev работают неполным составом. SUSPENDED тяжелее остальных состояний, пул перестал отдавать данные и требует работы с оборудованием.

Строка scan хранит дату последнего scrub, время выполнения и число исправленных ошибок. Запись «repaired 0B» после регулярных проверок говорит, что битых блоков нет.

Три счётчика READ, WRITE и CKSUM стоят в блоке config. CKSUM растёт, когда контрольные суммы не сходятся и данные восстанавливают с других дисков. Ненулевой CKSUM без роста ошибок чтения часто указывает на кабель, бэкплейн или контроллер, а не на сам накопитель.

Строка errors: No known data errors означает отсутствие известных повреждений. При появлении Permanent errors запустите zpool status -v: команда выведет список файлов и датасетов, которые не удалось восстановить. Такие файлы достают из снапшота или бэкапа, потому что внутри пула исправлять их нечем.

dmesg -T | grep -iE 'ata|nvme|i/o error|medium error|reset'

Вывод dmesg дополняет картину: строки вида medium error и reset controller появляются раньше, чем пул уходит в DEGRADED.

Проверка дисков через smartctl

smartctl -a /dev/sda
smartctl -t short /dev/sda
smartctl -t long /dev/sda
smartctl -a -d sat /dev/sda     # диск за USB-мостом
smartctl -a /dev/nvme0
IDАтрибутЧто означает рост
5Reallocated_Sector_CtПереназначенные секторы: десятки значений означают планирование замены
187Reported_UncorrectОшибки, которые накопитель не смог исправить
197Current_Pending_SectorСекторы в ожидании переназначения: любое значение выше нуля это повод менять диск
198Offline_UncorrectableСекторы, нечитаемые при офлайн-сканировании
199UDMA_CRC_Error_CountОшибки передачи по интерфейсу: проверьте кабель, порт и питание

Для NVMe вместо SATA-атрибутов смотрите строки Media and Data Integrity Errors, Available Spare и Percentage Used. Рост UDMA_CRC_Error_Count лечится заменой кабеля или переносом диска на другой порт, списывать накопитель раньше времени не нужно. Короткий тест smartctl -t short занимает пару минут, полный smartctl -t long идёт несколько часов и нагружает диск, поэтому планируйте его на окно обслуживания.

zfs list и zpool iostat: контроль места и нагрузки

zfs list -o space
zfs list -o name,used,usedbydataset,usedbychildren,usedbysnapshots,usedbyrefreservation
zpool iostat -v 5
zpool iostat -v -l 5

zfs list -o space разбивает used по источникам: сами данные датасета, потомки, снапшоты и резервирование. Снапшоты, которые живут месяцами, нередко занимают больше места, чем рабочие данные. Когда usedbysnapshots забирает треть объёма, пора пересматривать политику хранения.

zpool iostat -v показывает нагрузку по vdev и отдельным дискам. Ориентир по задержке: 1-3 мс для HDD и доли миллисекунды для NVMe. Рост latency при падении bandwidth обычно указывает на износ накопителя, ошибки контроллера или конкуренцию задач. Базовый чек-лист проверки нового пула приведён в руководстве по проверке и обслуживанию ZFS-пула после создания.

Обслуживание пула: scrubbing, resilvering и замена дисков

Scrubbing: плановая проверка целостности

zpool scrub tank
zpool status tank          # прогресс виден в строке scan
zpool scrub -p tank        # пауза
zpool scrub -s tank        # отмена

Scrub читает все блоки и сверяет контрольные суммы, при расхождении данные берутся с другого диска и перезаписываются. Для SATA-дисков достаточно ежемесячной проверки, для SAS и NVMe в нагруженных системах запускайте scrub раз в неделю. На пуле 100 ТБ из HDD проверка идёт 12-20 часов и заметно снижает скорость остальных операций, поэтому ставьте её на ночь или на выходные.

Не запускайте scrub, пока идёт resilvering, и не выключайте сервер посреди проверки: прерванный scrub после перезагрузки начнётся заново. Планировать проверки удобно через cron или systemd timer. В TrueNAS SCALE расписанием заведует отдельный раздел интерфейса, там же настраивают оповещения. Развёрнутая схема такого обслуживания собрана в статье о проактивном обслуживании ZFS в TrueNAS: мониторинг, scrub и замена дисков.

Замена диска: zpool replace и hot spare

zpool offline tank sdb
zpool replace tank sdb /dev/disk/by-id/ata-NEW-DISK
zpool status tank
zpool add tank spare /dev/disk/by-id/ata-SPARE

Порядок для отказавшего диска: отметьте его offline (для уже выпавшего в FAULTED шаг можно пропустить), затем выполните zpool replace с указанием старого и нового устройства. ZFS скопирует данные на новый накопитель и вернёт vdev к полному составу. Команда zpool online нужна, если вы вернули прежний диск в тот же vdev и хотите снова ввести его в работу.

Hot spare лежит в пуле готовым к работе. При отказе диска ZFS автоматически начнёт resilver на запасное устройство, и администратору останется заменить вышедший накопитель. Запасная железка на полке работает не хуже, но требует ручного zpool replace и увеличивает окно без избыточности.

Resilvering: что происходит и как не навредить

Resilver восстанавливает данные на новый диск по контрольным суммам и parity. Сканируется весь занятый объём, поэтому на пуле RAIDZ из дисков по 16 ТБ процесс легко занимает сутки и больше. Прогресс виден в строке scan вывода zpool status: процент, скорость и оставшееся время.

Пока идёт resilver, не запускайте scrub, не добавляйте диски в пул и не устраивайте тесты производительности. Параметры zfs_resilver_min_time_ms (по умолчанию 3000 мс) и zfs_scan_min_time_ms управляют долей времени, которую ZFS отдаёт работе с дисками. Их уменьшение ускоряет восстановление, но сильнее бьёт по отзывчивости пула для рабочих нагрузок. Меняйте настройки только при уверенности в запасе по производительности.

Снапшоты и репликация между системами хранения

Создание и удаление снапшотов

zfs snapshot tank/data@2026-09-11-before-upgrade
zfs list -t snapshot
zfs list -t snapshot -o name,used,refer tank/data
zfs destroy tank/data@2026-09-11-before-upgrade
zfs hold keep tank/data@backup-2026-09-01
zfs release keep tank/data@backup-2026-09-01

Снапшот занимает место только тогда, когда данные изменились: сразу после создания used равен нулю. Датасет на 500 ГБ со свежим снапшотом и изменившимися за сутки 2 ГБ займёт под снапшот именно эти 2 ГБ. Чем дольше живёт снапшот и чем активнее меняются данные, тем дороже он обходится.

Именуйте снапшоты с датой и причиной: через месяц вы не вспомните, зачем делали @snap1. Команда zfs hold защищает снапшот от удаления, в том числе от автоматической очистки sanoid. Флаг -r в zfs destroy рекурсивно сносит снапшоты датасета и его потомков, поэтому применяйте его после просмотра списка через zfs list -t snapshot.

Репликация через zfs send и zfs receive

# первичная копия
zfs snapshot tank/data@base
zfs send tank/data@base | ssh backup.zfs zfs receive backup/data

# инкремент: передаются только изменения между снапшотами
zfs send -i tank/data@base tank/data@daily-2026-09-11 | ssh backup.zfs zfs receive backup/data

# рекурсивно со свойствами и перезаписью цели при расхождении
zfs send -R tank/data@daily-2026-09-11 | ssh backup.zfs zfs receive -F backup/data

Ключ -i превращает полную передачу в инкрементальную: поток содержит только блоки, появившиеся между базовым и текущим снапшотом. Первая репликация большого датасета идёт часами, ночные инкременты по 5-10 ГБ проходят за минуты.

Флаг -R переносит датасеты вместе с потомками, свойствами и точками монтирования. Приём в существующий датасет без совпадения снапшотов упадёт, если не добавить -F: этот ключ откатывает целевую сторону до состояния отправителя и уничтожает данные, которых нет в потоке. Перед первой репликацией удостоверьтесь, что на втором сервере хватает места и версия OpenZFS не старше, чем на источнике. Для зашифрованных датасетов используйте zfs send -w с сырым потоком, иначе приём потребует ключа шифрования.

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

Автоматизация: sanoid и syncoid

[tank/data]
    use_template = production
    recursive = yes

[template_production]
    hourly = 36
    daily = 30
    monthly = 6
    autosnap = yes
    autoprune = yes

Sanoid создаёт и чистит снапшоты по расписанию из sanoid.conf, syncoid отправляет их на другой сервер. Команда репликации выглядит так:

syncoid --recursive tank/data backup.zfs:data

Запускайте sanoid через systemd timer или cron каждые 15 минут: тогда часовые снапшоты появляются вовремя, а старые удаляются по политике. Логи sanoid и syncoid читайте после каждого изменения конфигурации, иначе молча пропущенная ошибка репликации обнаружится в момент, когда бэкап действительно нужен. Если разбирать длинные логи автоматизации вручную не хочется, поток удобно прогнать через модель: AiTunnel даёт единый доступ к популярным нейросетям с оплатой в рублях и без VPN.

Расширение пула и управление квотами

Добавление дисков: zpool add и zpool attach

# расширить существующее зеркало: было два диска, станет три
zpool attach tank /dev/disk/by-id/ata-OLD /dev/disk/by-id/ata-NEW

# добавить новый vdev, например второе зеркало
zpool add tank mirror /dev/disk/by-id/ata-A /dev/disk/by-id/ata-B

# точка отката перед рискованной операцией
zpool checkpoint tank

zpool attach вводит диск в существующий vdev: зеркало из двух дисков становится зеркалом из трёх, избыточность растёт. zpool add создаёт новый vdev верхнего уровня, и пул начинает распределять блоки между ними. Второй вариант опасен добавлением страйпа без избыточности: его отказ уносит весь пул.

Одиночный диск в zpool add это распространённая ошибка. Добавляйте сразу зеркало или RAIDZ, даже если это удваивает расход железа.

RAIDZ долго не расширялся: добавить диск в существующий raidz1 vdev было нельзя, требовалась пересборка пула. В OpenZFS 2.3 появилась штатная RAIDZ expansion, и команда zpool attach tank raidz1-0 /dev/disk/by-id/ata-NEW добавляет диск к живому vdev. Процесс идёт постепенно, старые блоки сохраняют прежнюю ширину, поэтому свободное место прибавляется по мере перезаписи данных. На версиях до 2.3 такого механизма нет, и там расширение RAIDZ делают переносом на новый пул.

zpool checkpoint фиксирует состояние пула и позволяет вернуться к нему через zpool import --rewind-to-checkpoint. Точку отката стоит ставить перед zpool add, заменой дисков и любыми экспериментами. Checkpoint удерживает освободившееся место, поэтому удаляйте его командой zpool checkpoint -d tank, когда операция прошла успешно.

Квоты и резервирование: zfs set quota и reservation

zfs set quota=1T tank/data
zfs set quota=100G tank/home
zfs set userquota=50G tank/home
zfs set reservation=100G tank/vm
zfs set refreservation=200G tank/zvol
zfs get quota,reservation,used,available tank/data

quota ограничивает максимальный объём датасета вместе с потомками. Своего значения квоты дети не наследуют: данные дочернего датасета считаются в лимит родителя, а собственный лимит ему задают явно. Свойства userquota и groupquota ограничивают объём, который может занять конкретный пользователь или группа.

reservation гарантирует датасету место в пуле: зарезервированный объём не отдадут другим, даже если датасет его не использует. Для zvol применяйте refreservation, оно резервирует место под весь объём тома. Оба свойства уменьшают доступную ёмкость, и zpool list покажет больше занятого места, чем zfs list.

Квота ниже текущего объёма данных не удаляет файлы, но блокирует новые записи: приложение получит ENOSPC. Перед снижением лимита проверьте вывод zfs list -o space и удалите лишние снапшоты.

Типичные ошибки и как их избежать

Ошибки при создании и расширении пула

ОшибкаПоследствиеКак правильно
zpool create tank sda sdb без mirrorСтрайп: отказ любого диска убивает пулzpool create tank mirror /dev/disk/by-id/A /dev/disk/by-id/B
ashift=9 на дисках 4Kread-modify-write, падение случайной записи-o ashift=12 при создании пула
zpool add tank sdc вместо attachНовый vdev без избыточности, риск для всего пулаzpool add tank mirror sdc sdd
Имена /dev/sdX в конфигурацииПосле перезагрузки пул собирается из других устройств/dev/disk/by-id/... и проверка zpool status
recordsize=128K по умолчанию под базу данныхРост задержки и объёма записиzfs set recordsize=16K перед заливкой данных

Отдельно стоит проверить состав пула перед переносом данных: лишний страйп или потерянный диск в конфигурации видны только в zpool status. Общая картина возможностей и ограничений технологии собрана в статье о ZFS в программных системах хранения: возможности, ограничения и типовые ошибки.

Ошибки при обслуживании и замене дисков

ОшибкаПоследствиеКак правильно
Вынуть диск без zpool offlineПул уходит в DEGRADED, часть чтений падает с ошибкойzpool offline tank sdb, затем извлечение
Scrub во время resilveringКонкуренция за диски, окно без избыточности растягиваетсяДождаться завершения resilver, потом scrub
Перезагрузка до конца resilverПроцесс начинается заново, для RAIDZ это часы и суткиСледить за zpool status до ONLINE и нулевого scan
Игнорирование CKSUM и slow I/OПотеря избыточности остаётся незамеченнойПроверка zpool status после каждого события с железом
zfs destroy -r по снапшотамРекурсивное удаление всех снапшотов без возвратаУдалять без -r и после zfs list -t snapshot
autotrim=on на дешёвых SATA SSDПросадки производительности у части контроллеровТестировать под нагрузкой, при деградации вернуть off

Перед любой рискованной операцией делайте снапшот и zpool checkpoint, а изменения проверяйте на тестовом стенде: импорт копии пула в режиме zpool import -o readonly=on показывает, как поведёт себя конфигурация, и не трогает рабочие данные.

Материалы по теме

Поделиться:
Сохранить гайд? В закладки браузера