# sysrc zfs_enable="YES"Глава 23. Файловая система Z (ZFS)
Этот перевод может быть устаревшим. Для того, чтобы помочь с переводом, пожалуйста, обратитесь к Сервер переводов FreeBSD.
Содержание
ZFS — это продвинутая файловая система, разработанная для решения основных проблем, присущих предыдущему программному обеспечению подсистем хранения данных.
Первоначально разработанная в Sun Microsystems™, дальнейшая разработка открытой версии ZFS переместилась в проект OpenZFS.
ZFS имеет три основные цели проектирования:
Целостность данных: Все данные включают контрольную сумму. ZFS вычисляет контрольные суммы и записывает их вместе с данными. При последующем чтении этих данных ZFS пересчитывает контрольные суммы. Если контрольные суммы не совпадают, что означает обнаружение одной или нескольких ошибок данных, ZFS попытается автоматически исправить ошибки, если доступны двойные-, зеркальные- или блоки чётности.
Объединенное хранилище: добавление физических устройств хранения в пул и выделение пространства из этого общего пула. Пространство доступно для всех файловых систем и томов и увеличивается за счет добавления новых устройств хранения в пул.
Производительность: механизмы кэширования обеспечивают повышенную производительность. ARC — это продвинутый кэш для чтения, основанный на оперативной памяти. ZFS предоставляет второй уровень кэша для чтения на основе диска — L2ARC, а также кэш для синхронной записи на основе диска под названием ZIL.
Полный список возможностей и терминологии приведён в Особенности и терминология ZFS.
23.1. Что отличает ZFS от других
ZFS — это не просто файловая система, она принципиально отличается от традиционных файловых систем. Объединение традиционно разделённых ролей менеджера томов и файловой системы даёт ZFS уникальные преимущества. Теперь файловая система осведомлена о структуре нижележащих дисков. Традиционные файловые системы могли существовать только на одном диске. Если было два диска, приходилось создавать две отдельные файловые системы. Традиционная конфигурация аппаратного RAID решала эту проблему, предоставляя операционной системе один логический диск, состоящий из пространства физических дисков, поверх которого операционная система размещала файловую систему. Даже в программных решениях RAID, таких как предоставляемые GEOM, файловая система UFS, находящаяся поверх RAID, считает, что работает с одним устройством. Комбинация менеджера томов и файловой системы в ZFS решает эту проблему и позволяет создавать файловые системы, которые совместно используют общий пул доступного хранилища. Одно из больших преимуществ осведомленности ZFS о физической структуре дисков заключается в том, что существующие файловые системы автоматически расширяются при добавлении дополнительных дисков в пул. Это новое пространство становится доступным для файловых систем. ZFS также может применять разные свойства к каждой файловой системе. Это делает полезным создание отдельных файловых систем и наборов данных вместо единой монолитной файловой системы.
23.2. Краткое руководство по началу работы
Установщик FreeBSD может установить систему непосредственно в пул ZFS, конфигурация, известная как Root-on-ZFS; см. Разметка диска с использованием Root-on-ZFS с помощью мастера. В этом разделе показано, как создавать и управлять дополнительными пулами ZFS и наборами данных на работающей системе.
FreeBSD может монтировать пулы и наборы данных ZFS во время инициализации системы. Чтобы включить эту функцию, запустите:
Это добавляет zfs_enable="YES" в /etc/rc.conf. Выполнение service zfs enable вносит то же изменение.
Затем запустите службу:
# service zfs startПримеры в этом разделе предполагают использование трёх SATA-дисков с именами устройств ada0, ada1 и ada2. Пользователям оборудования SCSI/SAS следует использовать имена устройств da, пользователям оборудования NVMe — имена устройств nda.
23.2.1. Пул на одном диске
Сначала создайте раздел GPT на пустом диске. Затем добавьте раздел типа freebsd-zfs, из которого создается один нерезервируемый пул:
# gpart create -s gpt ada1
# gpart add -t freebsd-zfs ada1
# zpool create example /dev/ada1p1Для просмотра нового пула ознакомьтесь с выводом команды df:
# df /example
Filesystem 1K-blocks Used Avail Capacity Mounted on
example 17547136 0 17547136 0% /exampleЭтот вывод показывает создание и монтирование пула example, который теперь доступен как файловая система. Создайте файлы для пользователей, чтобы посмотреть, что все работает:
# cd /example
# ls
# touch testfile
# ls -al
total 4
drwxr-xr-x 2 root wheel 3 Aug 29 23:15 .
drwxr-xr-x 21 root wheel 512 Aug 29 23:12 ..
-rw-r--r-- 1 root wheel 0 Aug 29 23:15 testfileЭтот пул пока не использует расширенные функции и свойства ZFS. Чтобы создать набор данных в этом пуле с включённым сжатием:
# zfs create example/compressed
# zfs set compression=gzip example/compressedНабор данных example/compressed теперь представляет собой сжатую файловую систему ZFS. Попробуйте скопировать несколько больших файлов в /example/compressed.
Отключите сжатие с помощью:
# zfs set compression=off example/compressedЧтобы отмонтировать файловую систему, используйте zfs umount, а затем проверьте с помощью df:
# zfs umount example/compressed
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
example 17547008 0 17547008 0% /exampleДля повторного монтирования файловой системы, чтобы сделать её снова доступной, используйте zfs mount и проверьте с помощью df:
# zfs mount example/compressed
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
example 17547008 0 17547008 0% /example
example/compressed 17547008 0 17547008 0% /example/compressedВыполнение команды mount отображает пул и файловые системы:
# mount
/dev/ada0p1 on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ada0p2 on /usr (ufs, local, soft-updates)
example on /example (zfs, local)
example/compressed on /example/compressed (zfs, local)Используйте наборы данных ZFS как любую файловую систему после создания. Настраивайте другие доступные функции для каждого набора данных по мере необходимости. В примере ниже создаётся новая файловая система с именем data. Предполагается, что файловая система содержит важные файлы, и для неё настроено хранение двух копий каждого блока данных.
# zfs create example/data
# zfs set copies=2 example/dataИспользуйте df для просмотра данных и использования пространства:
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/ada0p1 2026030 235234 1628714 13% /
devfs 1 1 0 100% /dev
/dev/ada0p2 54098308 1032864 48737580 2% /usr
example 17547008 0 17547008 0% /example
example/compressed 17547008 0 17547008 0% /example/compressed
example/data 17547008 0 17547008 0% /example/dataОбратите внимание, что все файловые системы в пуле имеют одинаковое доступное пространство. Использование df в этих примерах показывает, что файловые системы занимают столько места, сколько им нужно, и все используют один и тот же пул. ZFS устраняет такие понятия, как тома и разделы, и позволяет нескольким файловым системам совместно использовать один пул.
Чтобы уничтожить файловые системы, а затем пул, который больше не нужен:
# zfs destroy example/compressed
# zfs destroy example/data
# zpool destroy example23.2.2. RAID-Z
Диски выходят из строя. Один из способов избежать потери данных при отказе диска — использование RAID. ZFS поддерживает эту возможность в своей конструкции пула. Пуллы RAID-Z требуют трёх или более дисков, но предоставляют больше полезного пространства, чем зеркальные пуллы.
Этот пример создает пул RAID-Z. Сначала на каждом диске создаются разделы GPT, затем укажите эти разделы GPT для добавления в пул с помощью ключевого слова raidz:
# gpart create -s gpt ada0
# gpart add -t freebsd-zfs ada0
# gpart create -s gpt ada1
# gpart add -t freebsd-zfs ada1
# gpart create -s gpt ada2
# gpart add -t freebsd-zfs ada2
# zpool create storage raidz ada0p1 ada1p1 ada2p1Рекомендовано использовать от трёх до девяти устройств в конфигурации RAID-Z. Для сред, требующих единого пула из 10 или более дисков, рекомендуется разбить его на меньшие группы RAID-Z. Если доступно два диска, ZFS-зеркалирование обеспечит избыточность при необходимости. Подробнее см. в zpool(8). |
Предыдущий пример создал пул storage. В этом примере в этом пуле создаётся новая файловая система с именем home:
# zfs create storage/homeВключить сжатие и сохранить дополнительную копию каталогов и файлов:
# zfs set copies=2 storage/home
# zfs set compression=gzip storage/homeЧтобы сделать это новым домашним каталогом для пользователей, скопируйте пользовательские данные в этот каталог и создайте соответствующие символические ссылки:
# cp -rp /home/* /storage/home
# rm -rf /home /usr/home
# ln -s /storage/home /home
# ln -s /storage/home /usr/homeДанные пользователя теперь хранятся в только что созданном /storage/home. Проверьте это, добавив нового пользователя и войдя в систему под его учётной записью.
Создайте снимок файловой системы для последующего отката:
# zfs snapshot storage/home@2026-07-11ZFS создаёт снимки набора данных, а не отдельного каталога или файла.
Символ @ является разделителем между именем файловой системы или тома и именем снимка. Перед удалением важного каталога создайте резервную копию файловой системы, а затем откатитесь к более раннему снимку, в котором каталог ещё существует:
# zfs rollback storage/home@2026-07-11Чтобы перечислить все доступные снимки, выполните команду ls в каталоге .zfs/snapshot файловой системы. Например, чтобы увидеть сделанный снимок:
# ls /storage/home/.zfs/snapshotНапишите скрипт для создания регулярных снимков пользовательских данных. Со временем снимки могут занимать много места на диске. Удалите предыдущий снимок с помощью команды:
# zfs destroy storage/home@2026-07-11После тестирования сделайте /storage/home настоящим /home с помощью следующей команды:
# zfs set mountpoint=/home storage/homeВыполните команды df и mount, чтобы убедиться, что система теперь распознает файловую систему как настоящий /home:
# mount
/dev/ada0p1 on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ada0p2 on /usr (ufs, local, soft-updates)
storage on /storage (zfs, local)
storage/home on /home (zfs, local)
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/ada0p1 2026030 235240 1628708 13% /
devfs 1 1 0 100% /dev
/dev/ada0p2 54098308 1032826 48737618 2% /usr
storage 26320512 0 26320512 0% /storage
storage/home 26320512 0 26320512 0% /homeНастройка RAID-Z завершена. Для добавления ежедневных отчётов о состоянии созданных файловых систем в ночные запуски periodic(8) добавьте следующую строку в /etc/periodic.conf:
daily_status_zfs_enable="YES"
periodic(8) также может выполнять запланированные проверки пула; см. Проверка пула.
23.2.3. Восстановление RAID-Z
Каждый программный RAID имеет метод контроля своего состояния. Просмотр состояния устройств RAID-Z осуществляется с помощью:
# zpool status -xЕсли все пулы находятся в состоянии онлайн и все работает нормально, сообщение будет следующим:
all pools are healthyЕсли возникла проблема, например, диск находится в состоянии оффлайн, состояние пула будет выглядеть так:
pool: storage
state: DEGRADED
status: One or more devices has been taken offline by the administrator.
Sufficient replicas exist for the pool to continue functioning in a
degraded state.
action: Online the device using 'zpool online' or replace the device with
'zpool replace'.
scan: none requested
config:
NAME STATE READ WRITE CKSUM
storage DEGRADED 0 0 0
raidz1-0 DEGRADED 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 OFFLINE 0 0 0
ada2p1 ONLINE 0 0 0
errors: No known data errors"OFFLINE" показывает, что администратор перевел ada1p1 в автономный режим с помощью:
# zpool offline storage ada1p1Выключите компьютер и замените диск ada1p1. Заново создайте GPT-раздел типа freebsd-zfs на новом диске. Включите компьютер и верните ada1p1 в пул:
# zpool replace storage ada1p1Далее снова проверьте статус, на этот раз без -x, чтобы отобразить все пулы:
# zpool status storage
pool: storage
state: ONLINE
scan: resilvered 3.21G in 00:04:36 with 0 errors on Sat Jul 11 10:32:19 2026
config:
NAME STATE READ WRITE CKSUM
storage ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
ada2p1 ONLINE 0 0 0
errors: No known data errorsВ этом примере все в порядке.
23.2.4. Проверка данных
ZFS использует контрольные суммы для проверки целостности хранимых данных. Создание файловых систем автоматически включает их.
Отключение контрольных сумм возможно, но не рекомендуется! Контрольные суммы занимают мало места и обеспечивают целостность данных. Большинство функций ZFS не будут работать корректно при отключённых контрольных суммах. Их отключение не приведет к заметному повышению производительности. |
Проверка контрольных сумм данных (называемая scrubbing) обеспечивает целостность пула storage с помощью:
# zpool scrub storageПродолжительность очистки зависит от объёма хранимых данных. Большие объёмы данных требуют пропорционально больше времени для проверки. Поскольку очистка интенсивно использует операции ввода-вывода, ZFS позволяет выполнять только одну очистку на каждом пуле одновременно. После завершения очистки просмотрите статус с помощью zpool status:
# zpool status storage
pool: storage
state: ONLINE
scan: scrub repaired 0B in 00:19:16 with 0 errors on Sat Jul 11 10:32:19 2026
config:
NAME STATE READ WRITE CKSUM
storage ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
ada2p1 ONLINE 0 0 0
errors: No known data errorsОтображение даты завершения последней очистки помогает определить, когда начать следующую. Регулярная очистка защищает данные от тихих повреждений и гарантирует целостность пула.
23.3. Администрирование zpool
Управление ZFS осуществляется с помощью двух основных утилит. Утилита zpool контролирует работу пула и позволяет добавлять, удалять, заменять и управлять дисками. Утилита zfs позволяет создавать, уничтожать и управлять наборами данных, включая как файловые системы, так и тома.
23.3.1. Создание и удаление пулов хранения данных
Самое важное решение при создании пула хранения ZFS — это выбор типов vdev для группировки физических дисков. См. список типов vdev для получения подробной информации о возможных вариантах. Типы vdev определяют характеристики избыточности, ёмкости и производительности пула. Раскладка пула не фиксируется навсегда при его создании. Зеркала позволяют добавлять новые диски в vdev, а полосы (stripes) обновляются до зеркал путём присоединения нового диска к vdev. Vdev RAID-Z увеличиваются на один диск за раз с помощью расширения RAID-Z, которое требует OpenZFS 2.3 или более поздней версии, впервые доступной во FreeBSD 15.0. Добавление новых vdev расширяет пул в любое время, а удаление верхних уровней vdev возможно в определённых пределах. Изменение формы активного пула занимает время и пропускную способность ввода-вывода, поэтому выбор подходящих типов vdev заранее остаётся важным.
Создайте простой зеркальный пул на дисках, содержащих GPT-разделы типа freebsd-zfs:
# zpool create mypool mirror /dev/ada1p1 /dev/ada2p1
# zpool status
pool: mypool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
ada2p1 ONLINE 0 0 0
errors: No known data errorsЧтобы создать более одного vdev одной командой, укажите группы дисков, разделённые ключевым словом типа vdev, в данном примере mirror:
# zpool create mypool mirror /dev/ada1p1 /dev/ada2p1 mirror /dev/ada3p1 /dev/ada4p1
# zpool status
pool: mypool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
ada2p1 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ada3p1 ONLINE 0 0 0
ada4p1 ONLINE 0 0 0
errors: No known data errorsПулы также могут использовать разделы вместо целых дисков. Размещение ZFS в отдельном разделе позволяет одному диску иметь другие разделы для иных целей. В частности, это позволяет добавлять разделы с загрузочным кодом и файловыми системами, необходимыми для загрузки. Это даёт возможность загружаться с дисков, которые также являются членами пула. ZFS не приводит к снижению производительности на FreeBSD при использовании раздела вместо целого диска. Использование разделов также позволяет администратору недоиспользовать диски, задействуя не всю их емкость. Если будущий заменяемый диск того же номинального размера, что и оригинальный, на самом деле имеет немного меньшую емкость, меньший раздел все равно поместится на заменяемом диске.
Создание пула RAID-Z2 с использованием разделов:
# zpool create mypool raidz2 /dev/ada0p1 /dev/ada1p1 /dev/ada2p1 /dev/ada3p1 /dev/ada4p1 /dev/ada5p1
# zpool status
pool: mypool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
ada2p1 ONLINE 0 0 0
ada3p1 ONLINE 0 0 0
ada4p1 ONLINE 0 0 0
ada5p1 ONLINE 0 0 0
errors: No known data errorsZFS выравнивает и подбирает размер своих минимальных записей для каждого vdev на основе значения ashift этого vdev, которое является логарифмом размера сектора по основанию 2. OpenZFS определяет размер сектора, сообщаемый дисками при создании vdev, и выбирает ashift соответствующим образом. Некоторые диски сообщают секторы в 512 байт для совместимости, но внутренне используют секторы в 4096 байт. Создавайте пулы на таких дисках с явным параметром -o ashift=12, чтобы принудительно установить выравнивание по 4096 байт:
# zpool create -o ashift=12 mypool mirror /dev/ada1p1 /dev/ada2p1Установка переменной sysctl(8) vfs.zfs.vdev.min_auto_ashift в значение 12 дает тот же результат для создания пула и для последующих операций zpool add и zpool attach. ashift — это свойство каждого vdev, а не пула в целом. Оно фиксируется при создании vdev и не может быть изменено впоследствии, поэтому проверьте его перед записью данных в пул.
Уничтожьте пул, который больше не нужен, чтобы повторно использовать диски. Перед уничтожением пула необходимо размонтировать файловые системы в этом пуле. Если какой-либо набор данных используется, операция размонтирования завершится неудачей без уничтожения пула. Принудительное уничтожение пула выполняется с помощью -f. Это может привести к неопределённому поведению приложений, у которых были открыты файлы в этих наборах данных.
23.3.2. Свойства пулов
Подобно наборам данных, пулы имеют свойства, которые сообщают о состоянии и управляют поведением. Отобразите каждое свойство пула с помощью zpool get all mypool или укажите конкретные свойства:
# zpool get health,capacity mypool
NAME PROPERTY VALUE SOURCE
mypool health ONLINE -
mypool capacity 27% -Измените изменяемое свойство с помощью zpool set:
# zpool set comment="Backup pool" mypool
# zpool get comment mypool
NAME PROPERTY VALUE SOURCE
mypool comment Backup pool localТакие свойства, как size, capacity, fragmentation и health, являются статусными значениями только для чтения. Другие изменяют поведение пула; в этой главе используется autoexpand для автоматического расширения пула (Увеличение размера пула), autoreplace с горячими резервными дисками (Горячие резервные диски и автоматическая замена с помощью zfsd), autotrim на пулах с SSD (TRIM and Initialization) и compatibility для переносимых пулов (Обновление пула дисков). Устанавливайте свойства при создании пула, передавая -o команде zpool create, как показано выше с ashift. zpoolprops(7) описывает все свойства пула.
23.3.3. Добавление и удаление устройств
Существует два способа добавления дисков в пул: подключение диска к существующему vdev с помощью zpool attach или добавление vdev в пул с помощью zpool add. Некоторые типы vdev позволяют добавлять диски в vdev после его создания. Виртуальные устройства (vdev) RAID-Z принимают новые диски исключительно посредством расширения RAID-Z.
Пул, созданный с одним диском, не обладает избыточностью. Он может обнаружить повреждение данных, но не может его исправить, так как нет другой копии данных. Свойство Копии (copies) может восстановить данные после небольшого сбоя, например, повреждённого сектора, но не обеспечивает такой же уровень защиты, как зеркалирование или RAID-Z. Начиная с пула, состоящего из однодискового vdev, используйте zpool attach для добавления нового диска в vdev, создавая зеркало. Также используйте zpool attach для добавления новых дисков в зеркальную группу, увеличивая избыточность и производительность чтения. При разметке дисков, используемых для пула, повторите разметку первого диска на втором. Используйте gpart backup и gpart restore для упрощения этого процесса.
Обновите однодисковый vdev (stripe) ada0p3 до зеркала, присоединив ada1p3:
# zpool status
pool: mypool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
errors: No known data errors
# zpool attach mypool ada0p3 ada1p3
Make sure to wait until resilver is done before rebooting.
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
partcode written to ada1p1
bootcode written to ada1
# zpool status
pool: mypool
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Sat Jul 11 11:15:25 2026
738M scanned at 105M/s, 522M issued at 74.6M/s, 781M total
522M resilvered, 66.84% done, 00:00:03 to go
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0 (resilvering)
errors: No known data errors
# zpool status
pool: mypool
state: ONLINE
scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 11:18:36 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
errors: No known data errorsЕсли добавление дисков к существующему vdev невозможно, альтернативным методом является добавление другого vdev в пул. Добавление vdev повышает производительность за счет распределения записей между vdev. Каждый vdev обеспечивает свою собственную избыточность. Возможно смешивание типов vdev, таких как mirror и RAID-Z, но это не рекомендуется. Добавление не избыточного vdev к пулу, содержащему mirror или RAID-Z vdev, подвергает риску данные во всем пуле. Распределение записей означает, что отказ не избыточного диска приведет к потере части каждого блока, записанного в пул.
ZFS распределяет данные по всем vdev. Например, при использовании двух зеркальных vdev это фактически эквивалентно RAID 10, где записи распределяются по двум наборам зеркал. ZFS выделяет пространство таким образом, что каждый vdev достигает 100% заполненности одновременно. Наличие vdev с разным количеством свободного места снижает производительность, так как больше данных записывается на менее заполненный vdev.
При подключении новых устройств к загрузочному пулу не забудьте обновить загрузочный код.
Присоедините вторую группу зеркал (ada2p3 и ada3p3) к существующему зеркалу:
# zpool status
pool: mypool
state: ONLINE
scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 12:11:56 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
errors: No known data errors
# zpool add mypool mirror ada2p3 ada3p3
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
partcode written to ada2p1
bootcode written to ada2
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada3
partcode written to ada3p1
bootcode written to ada3
# zpool status
pool: mypool
state: ONLINE
scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 09:58:28 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
ada3p3 ONLINE 0 0 0
errors: No known data errorszpool add также присоединяет выделенные устройства журнала и кэша к существующему пулу. Журнал vdev хранит журнал намерений ZFS на отдельном хранилище с низкой задержкой, ускоряя синхронные записи, такие как те, что выполняются базами данных и NFS. Зеркалируйте устройства журнала, потому что потеря незеркалированного устройства журнала вместе с сбоем системы стоит пулу последних нескольких секунд синхронных записей; см. раздел Синхронные записи, ZIL и SLOG для рекомендаций по размеру и настройке. Кэш vdev расширяет ARC вторым уровнем кэша чтения на быстром хранилище. Устройства кэша не требуют избыточности, так как ZFS вместо этого читает любой блок, который не удалось прочитать из кэша, с исходных дисков пула. Содержимое кэша, L2ARC, по умолчанию сохраняется после перезагрузки.
Добавьте зеркальный журнальный vdev и NVMe-устройство кэша к существующему пулу:
# zpool add mypool log mirror ada4p2 ada5p2
# zpool add mypool cache nda0p2
# zpool status mypool
pool: mypool
state: ONLINE
scan: resilvered 781M in 00:00:16 with 0 errors on Sat Jul 11 09:58:28 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
ada3p3 ONLINE 0 0 0
logs
mirror-2 ONLINE 0 0 0
ada4p2 ONLINE 0 0 0
ada5p2 ONLINE 0 0 0
cache
nda0p2 ONLINE 0 0 0
errors: No known data errorsКоманда zpool detach удаляет отдельные диски из зеркального виртуального устройства (vdev) при условии сохранения достаточной избыточности. Если в группе зеркала остаётся единственный диск, эта группа перестает быть зеркалом и становится страйпом, что подвергает весь пул риску в случае выхода из строя оставшегося диска.
Удалить диск из трёхдисковой зеркальной группы:
# zpool status
pool: mypool
state: ONLINE
scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
errors: No known data errors
# zpool detach mypool ada2p3
# zpool status
pool: mypool
state: ONLINE
scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
errors: No known data errorszpool remove удаляет целые vdev верхнего уровня из пула. ZFS эвакуирует vdev, копируя все выделенные ему данные на другие vdev в пуле, а затем отсоединяет диски. Удаление работает для горячих резервов, кэша, журналов, специальных и дедупликационных устройств, а также для data vdev, которые являются одиночными дисками или зеркалами. Data vdev не могут быть удалены из пулов, содержащих vdev RAID-Z верхнего уровня, и все vdev верхнего уровня в пуле должны использовать одинаковый ashift. Эвакуация выполняется в фоновом режиме, и пул остается онлайн на протяжении всего процесса; следите за прогрессом с помощью zpool status. После завершения удаления ZFS сохраняет таблицу в памяти, сопоставляющую блоки удаленного vdev с их новыми местоположениями. Таблица небольшая, но постоянная; zpool remove -n оценивает использование памяти перед началом удаления.
Удалите один из двух зеркальных vdev из пула:
# zpool remove mypool mirror-1
# zpool status mypool
pool: mypool
state: ONLINE
scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
remove: Evacuation of mirror in progress since Sat Jul 11 10:15:31 2026
1.71G copied out of 2.32G at 111M/s, 73.71% done, 0h0m to go
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
ada3p3 ONLINE 0 0 0
errors: No known data errors
# zpool status mypool
pool: mypool
state: ONLINE
scan: scrub repaired 0B in 00:01:11 with 0 errors on Sat Jul 11 03:14:02 2026
remove: Removal of vdev 1 copied 2.32G in 0h0m, completed on Sat Jul 11 10:15:53 2026
10.9K memory used for removed device mappings
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
indirect-1 ONLINE 0 0 0
errors: No known data errorsЗапись indirect-1 является заполнителем для переотображённых блоков удалённого vdev и не содержит дисков. Отмените выполняющееся удаление с помощью zpool remove -s.
23.3.4. Расширение RAID-Z
Расширение RAID-Z увеличивает существующий vdev RAID-Z на один диск за раз, не изменяя его уровень чётности.
Расширение RAID-Z требует OpenZFS 2.3 или более поздней версии, впервые доступной в FreeBSD 15.0. Пулы, созданные в более ранних версиях, требуют включения функции |
Чтобы расширить vdev RAID-Z, выполните zpool attach, указав имя vdev RAID-Z, как показано в zpool status, и новый диск:
# zpool attach mypool raidz2-0 ada6p3Расширение перераспределяет существующие данные по увеличенному набору дисков в фоновом режиме, при этом пул остается online и используется. Добавьте -w, чтобы заставить zpool attach ожидать завершения расширения. zpool status сообщает о ходе выполнения в строке expand::
# zpool status mypool
pool: mypool
state: ONLINE
scan: scrub repaired 0B in 06:14:36 with 0 errors on Sat Jul 11 04:31:19 2026
expand: expansion of raidz2-0 in progress since Sat Jul 11 09:42:12 2026
1.83T / 5.36T copied at 186M/s, 34.14% done, 05:31:43 to go
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
ada3p3 ONLINE 0 0 0
ada4p3 ONLINE 0 0 0
ada5p3 ONLINE 0 0 0
ada6p3 ONLINE 0 0 0
errors: No known data errorsКогда расширение завершается, ёмкость нового диска становится доступной:
# zpool status mypool | grep expand:
expand: expanded raidz2-0 copied 5.36T in 08:23:35, on Sat Jul 11 18:05:47 2026Блоки, записанные до расширения, сохраняют прежнее соотношение данных и чётности и продолжают занимать место соответствующим образом. Таким образом, полный прирост ёмкости от нового диска применяется к данным, записанным после расширения, тогда как старые данные выигрывают только при перезаписи, например, с помощью zfs rewrite. Повторите процедуру для увеличения vdev на несколько дисков, подключая их по одному.
23.3.5. Пулы dRAID
dRAID — это вариант RAID-Z, который распределяет резервную емкость горячего резерва по всем дискам в vdev. dRAID vdev состоит из внутренних групп RAID-Z плюс опциональных распределенных резервов, равномерно распределенных по каждому диску. Когда диск выходит из строя, ZFS выполняет перестроение в распределенный резерв, читая и записывая на все оставшиеся диски параллельно, завершая процесс за долю времени, которое требуется для ресилверинга на один резервный диск. Замена вышедшего из строя диска затем перестраивает его из распределенного резерва, восстанавливая полную защиту. dRAID ориентирован на пулы с множеством дисков, где время перестроения RAID-Z становится опасно большим.
Тип vdev описывает полную компоновку, согласно zpoolconcepts(7):
draid[parity][:datad][:childrenc][:sparess]
parity — это уровень чётности внутренних групп, от 1 до 3, по умолчанию 1. data — это количество устройств данных на группу резервирования, по умолчанию 8. children — это общее количество дисков, служащее перекрестной проверкой при перечислении многих устройств. spares — это количество распределенных горячих резервов, по умолчанию 0.
Создайте пул из 24-дискового vdev dRAID с двойной четностью, 8 дисками данных на группу избыточности и 2 распределенными резервными дисками:
# zpool create mypool draid2:8d:24c:2s ada0 ada1 ada2 ada3 ada4 ada5 ada6 ada7 ada8 ada9 ada10 ada11 ada12 ada13 ada14 ada15 ada16 ada17 ada18 ada19 ada20 ada21 ada22 ada23Распределенные запасные диски отображаются в разделе spares в zpool status, с именами вроде draid2-0-0 для первого запасного диска первого vdev.
dRAID обменивает эффективность использования пространства на скорость перестроения. В отличие от RAID-Z, dRAID использует фиксированную ширину полосы, дополняя мелкие записи нулями. При стандартных 8 дисках данных и секторах 4 КБ минимальное выделение составляет 32 КБ, что снижает полезную ёмкость и эффективность сжатия для наборов данных, где преобладают мелкие блоки. Ёмкость распределённых запасных дисков также резервируется заранее, независимо от того, произойдёт ли сбой диска когда-либо. Объединение пула dRAID со специальным vdev удерживает метаданные и мелкие блоки вне широких полос и возвращает большую часть потерянной эффективности. Для пулов с несколькими дисками RAID-Z остаётся лучшим выбором.
23.3.6. Специальные классы выделения
Специальные классы выделения привязывают vdev-устройства к конкретным типам данных пула. Vdev special хранит метаданные пула, такие как непрямые блоки и dnode, а также, опционально, блоки данных небольших файлов. Vdev dedup хранит таблицы дедупликации. Размещение этих метаданных на быстрых устройствах, таких как зеркала NVMe, ускоряет операции, требовательные к метаданным, например обход каталогов, zfs list и поиск при дедупликации в пулах, состоящих в остальном из более медленных дисков.
Добавьте зеркальный специальный vdev к существующему пулу:
# zpool add mypool special mirror nda0 nda1Новые выделения метаданных затем направляются в специальный vdev; существующие метаданные остаются на месте, пока не будут перезаписаны.
Установка свойства special_small_blocks набора данных позволяет специальному vdev хранить блоки данных размером до указанного значения:
# zfs set special_small_blocks=16K mypool/projectsДопустимые значения — ноль, который отключает хранение блоков данных в специальном классе, или степень двойки от 512 байт до 1 МБ в FreeBSD 14.x; FreeBSD 15.0 принимает значения вплоть до максимального размера блока в 16 МБ. Установка этого свойства на recordsize набора данных отправляет все блоки данных этого набора данных в специальный класс. Когда специальный vdev заполняется, новые выделения перетекают обратно в обычный класс вместо сбоя.
Специальный vdev — это не кэш. Он хранит единственную копию метаданных пула, выделенных ему, и его потеря уничтожает пул. Согласуйте избыточность special и dedup vdev с избыточностью data vdev, например, используя зеркало. |
Удаление специального или дедупликационного vdev с помощью zpool remove возможно с учётом ограничений, описанных в Добавление и удаление устройств. На практике требование соответствия ashift часто препятствует удалению, когда специальный vdev использует устройства с иным размером сектора, чем data vdev.
23.3.7. Проверка состояния пула
Статус пула важен. Если диск отключается или ZFS обнаруживает ошибку чтения, записи или контрольной суммы, соответствующий счетчик ошибок увеличивается. Вывод команды status показывает конфигурацию и состояние каждого устройства в пуле, а также состояние всего пула. Также отображаются действия, которые следует предпринять, и детали последнего scrub.
# zpool status
pool: mypool
state: ONLINE
scan: scrub repaired 0B in 02:25:36 with 0 errors on Sat Jul 11 06:51:26 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
ada3p3 ONLINE 0 0 0
ada4p3 ONLINE 0 0 0
ada5p3 ONLINE 0 0 0
errors: No known data errorsОпции подстраивают вывод под конкретную задачу:
-vвыводит подробную информацию об ошибках данных, печатая полный список ошибок, обнаруженных с момента последней полной очистки пула, включая имена затронутых файлов.-xотображает состояние пулов с ошибками или пулов, которые в противном случае недоступны, скрывая исправные пулы.-sотображает количество медленных операций ввода-вывода на каждом конечном vdev, то есть операций, которые не завершились в течение 30 секунд.-eотображает только неисправные vdev, сокращая вывод для пулов с большим количеством устройств; этот флаг требует FreeBSD 14.1 или более поздней версии.-pотображает числа как точные, разбираемые значения вместо округлённых, удобочитаемых.-tотображает статус TRIM для каждого vdev.
См. zpool-status(8) для полного списка опций.
23.3.8. Сброс состояния ошибки
При обнаружении ошибки ZFS увеличивает счетчики ошибок чтения, записи или контрольных сумм. Чтобы очистить сообщение об ошибке и сбросить счетчики, используйте команду zpool clear mypool. Сброс состояния ошибки может быть важен для автоматизированных скриптов, которые уведомляют администратора при возникновении ошибки в пуле. Без очистки старых ошибок скрипты могут не сообщать о новых ошибках.
23.3.9. Замена рабочего устройства
Может потребоваться заменить один диск на другой. При замене рабочего диска процесс сохраняет старый диск в режиме онлайн во время замены. Пул никогда не переходит в состояние деградировавшего, что снижает риск потери данных. Выполнение команды zpool replace копирует данные со старого диска на новый. После завершения операции ZFS отключает старый диск от vdev. Если новый диск больше старого, можно расширить zpool, используя новое пространство. См. Расширение пула.
Заменить работающее устройство в пуле:
# zpool status
pool: mypool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
errors: No known data errors
# zpool replace mypool ada1p3 ada2p3
Make sure to wait until resilvering finishes before rebooting.
When booting from the pool 'mypool', update the boot code on the newly attached disk 'ada2p3'.
Assuming GPT partitioning is used and ada0 is the new boot disk, use the following command:
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
# zpool status
pool: mypool
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Sat Jul 11 14:21:35 2026
781M / 781M scanned, 604M / 781M issued at 101M/s
604M resilvered, 77.39% done, 00:00:01 to go
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
replacing-1 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0 (resilvering)
errors: No known data errors
# zpool status
pool: mypool
state: ONLINE
scan: resilvered 781M in 00:00:17 with 0 errors on Sat Jul 11 14:21:52 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
errors: No known data errorsНа зеркальных vdev-устройствах добавление -s к zpool replace или zpool attach выполняет последовательное восстановление вместо восстанавливающего ресильверинга. Последовательное восстановление копирует данные в порядке расположения на диске без проверки контрольных сумм каждого блока, восстанавливая избыточность гораздо быстрее. Поскольку копирование пропускает проверку контрольных сумм, ZFS автоматически запускает scrub пула после завершения последовательного восстановления. Последовательное восстановление работает на зеркальных и dRAID vdev-устройствах, но не на RAID-Z. Перезапустите текущий resilver с начала с помощью zpool resilver mypool.
23.3.10. Обработка неисправных устройств
Когда диск в пуле выходит из строя, устройство vdev, к которому принадлежит этот диск, переходит в деградировавшее состояние. Данные остаются доступными, но с пониженной производительностью, поскольку ZFS вычисляет недостающие данные из доступной избыточности. Чтобы восстановить устройство vdev в полностью работоспособное состояние, замените вышедший из строя физический диск. Затем ZFS получает указание начать операцию восстановления. ZFS пересчитывает данные с вышедшего из строя устройства из доступной избыточности и записывает их на заменённый диск. После завершения процесса устройство vdev возвращается в состояние онлайн.
Если vdev не имеет избыточности или если устройства вышли из строя и недостаточно избыточности для компенсации, пул переходит в состояние faulted. Если недостаточно устройств для восстановления связи, пул становится неработоспособным, что требует восстановления данных из резервных копий.
При замене вышедшего из строя диска имя отказавшего диска изменяется на GUID нового диска. Новый параметр имени устройства для zpool replace не требуется, если заменяющее устройство имеет то же имя устройства.
Заменить вышедший из строя диск с помощью zpool replace:
# zpool status
pool: mypool
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-2Q
config:
NAME STATE READ WRITE CKSUM
mypool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
ada0p3 ONLINE 0 0 0
316502962686821739 UNAVAIL 0 0 0 was /dev/ada1p3
errors: No known data errors
# zpool replace mypool 316502962686821739 ada2p3
# zpool status
pool: mypool
state: DEGRADED
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Sat Jul 11 14:52:21 2026
781M / 781M scanned, 641M / 781M issued at 128M/s
640M resilvered, 82.04% done, 00:00:01 to go
config:
NAME STATE READ WRITE CKSUM
mypool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
ada0p3 ONLINE 0 0 0
replacing-1 UNAVAIL 0 0 0
15732067398082357289 UNAVAIL 0 0 0 was /dev/ada1p3/old
ada2p3 ONLINE 0 0 0 (resilvering)
errors: No known data errors
# zpool status
pool: mypool
state: ONLINE
scan: resilvered 781M in 00:00:17 with 0 errors on Sat Jul 11 14:52:38 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
errors: No known data errors23.3.11. Горячие резервные диски и автоматическая замена с помощью zfsd
Пулы с избыточными vdev могут регистрировать горячие резервные диски, которые находятся в режиме ожидания для замены вышедшего из строя устройства. Резервный диск должен быть не меньше устройства, которое он заменяет. Укажите резервные диски при создании пула, перечислив их после ключевого слова spare, как в zpool create mypool mirror ada0p3 ada1p3 spare ada3p3, или добавьте их в существующий пул с помощью zpool add:
# zpool add mypool spare ada3p3
# zpool status
pool: mypool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
spares
ada3p3 AVAIL
errors: No known data errorsЗапасной диск остается неиспользуемым, отображаясь как AVAIL, пока устройство не выйдет из строя. Активируйте запасной диск вручную с помощью zpool replace, указав отказавшее устройство и запасной диск:
# zpool replace mypool ada1p3 ada3p3
# zpool status
pool: mypool
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-2Q
scan: resilvered 781M in 00:00:21 with 0 errors on Sat Jul 11 09:14:33 2026
config:
NAME STATE READ WRITE CKSUM
mypool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
ada0p3 ONLINE 0 0 0
spare-1 DEGRADED 0 0 0
ada1p3 UNAVAIL 0 0 0 cannot open
ada3p3 ONLINE 0 0 0
spares
ada3p3 INUSE currently in use
errors: No known data errorsЗапасной диск является временной мерой, и пул остается в этом состоянии, пока администратор не разрешит ситуацию. После физической замены вышедшего из строя диска и повторного зеркалирования нового устройства с помощью zpool replace, верните запасной диск в режим ожидания с помощью zpool detach mypool ada3p3. Чтобы вместо этого повысить запасной диск до постоянного члена vdev, отсоедините вышедшее из строя устройство с помощью zpool detach mypool ada1p3.
Свойство пула autoreplace, по умолчанию выключенное, управляет тем, что происходит, когда новый диск появляется в том же физическом месте, что и устройство, ранее принадлежавшее пулу. При установке autoreplace в значение on, ZFS автоматически заменяет старое устройство новым диском, не требуя команды zpool replace:
# zpool set autoreplace=on mypoolНа FreeBSD автоматические реакции на сбои, включая выполнение autoreplace, выполняются zfsd(8), демоном управления отказами ZFS в базовой системе. Демон не включён по умолчанию. Включите и запустите его с помощью команды:
# sysrc zfsd_enable="YES"
# service zfsd startzfsd(8) прослушивает события пула и:
Активирует горячий резерв, когда устройство исчезает из избыточного vdev или когда vdev становится деградировавшим или неисправным.
Отмечает vdev как отказавший, когда он создает более 50 ошибок ввода-вывода или более 8 отложенных операций ввода-вывода за период в 60 секунд, затем активирует горячий резерв.
Помечает vdev как деградировавший, когда он генерирует более 50 ошибок контрольной суммы за 60-секундный период, затем активирует горячий резерв.
Возвращает устройство в онлайн-режим, когда оно снова появляется, запуская ресильверинг данных, записанных, пока оно отсутствовало.
Заменяет отсутствующее устройство новым диском, который появляется в том же физическом местоположении, когда в пуле установлено значение
autoreplaceвon.Возвращает горячие резервы в режим ожидания после завершения ресильвера постоянной замены.
FreeBSD использует zfsd(8) для управления отказами. Демон событий ZFS (ZED), присутствующий на платформах Linux OpenZFS, не является частью FreeBSD. |
Изучите поток событий, который управляет этими решениями, с помощью zpool events. Добавление -v показывает полную полезную нагрузку каждого события, а -f оставляет команду работающей, выводя новые события по мере их поступления. ZFS также доставляет эти события в devd(8). Правила в /etc/devd/zfs.conf записывают их в системный журнал и служат шаблоном для пользовательских действий, таких как отправка почты при деградации пула.
23.3.12. Чистка пула
Регулярно выполняйте scrub для пулов, желательно не реже одного раза в месяц. Операция scrub интенсивно использует диски и может снизить производительность во время выполнения. Избегайте периодов высокой нагрузки при планировании scrub или снизьте его влияние с помощью настраиваемых параметров планировщика ввода-вывода, описанных в разделе «Настройка».
# zpool scrub mypool
# zpool status
pool: mypool
state: ONLINE
scan: scrub in progress since Sat Jul 11 20:52:54 2026
130G / 8.60T scanned at 649M/s, 116G / 8.60T issued at 580M/s
0B repaired, 1.32% done, 04:15:41 to go
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 0 0 0
ada2p3 ONLINE 0 0 0
ada3p3 ONLINE 0 0 0
ada4p3 ONLINE 0 0 0
ada5p3 ONLINE 0 0 0
errors: No known data errorsПриостановите выполняющуюся проверку с помощью zpool scrub -p mypool, если она мешает другой работе; повторный запуск zpool scrub mypool возобновит её с того места, где она остановилась. Чтобы вместо этого отменить операцию проверки, выполните zpool scrub -s mypool. Команда zpool scrub -w mypool ожидает завершения проверки перед возвратом, что полезно в скриптах. Если после проверки сообщается об ошибках, zpool scrub -e mypool выполняет проверку ошибок, которая повторно проверяет только блоки с известными ошибками, завершаясь гораздо быстрее, чем полная проверка. Проверка ошибок требует OpenZFS 2.2, впервые включённого в FreeBSD 14.0.
periodic(8) может автоматически запускать проверки. Чтобы проверить каждый пул, последняя проверка которого была более 35 дней назад, добавьте эту строку в /etc/periodic.conf:
daily_scrub_zfs_enable="YES"
Установите daily_scrub_zfs_default_threshold="дней", чтобы изменить количество дней между проверками. periodic.conf(5) также описывает пороговые значения для отдельных пулов. Установка daily_status_zfs_enable="YES" добавляет проверку состояния пула в ежедневный отчёт periodic(8).
23.3.13. Самолечение
Контрольные суммы, хранимые с блоками данных, позволяют файловой системе самовосстанавливаться. Эта функция автоматически исправляет данные, контрольная сумма которых не совпадает с записанной на другом устройстве, входящем в состав пула хранения. Например, в конфигурации зеркала с двумя дисками, где один из дисков начинает работать со сбоями и больше не может корректно хранить данные. Это становится ещё хуже, если данные долгое время не были доступны, как в случае долгосрочного архивного хранения. Традиционные файловые системы требуют выполнения команд для проверки и исправления данных, таких как fsck(8). Эти команды занимают время, а в сложных случаях администратору приходится выбирать, какую операцию восстановления выполнить. Когда ZFS обнаруживает блок данных с несовпадающей контрольной суммой, он пытается прочитать данные с зеркального диска. Если этот диск может предоставить корректные данные, ZFS передаст их приложению и исправит данные на диске с ошибочной контрольной суммой. Это происходит без какого-либо вмешательства администратора в ходе обычной работы пула.
Следующий пример демонстрирует самовосстановление при создании зеркального пула из разделов /dev/ada0p1 и /dev/ada1p1.
# zpool create healer mirror /dev/ada0p1 /dev/ada1p1
# zpool status healer
pool: healer
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
healer ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
errors: No known data errors
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
healer 960M 111K 960M - - 0% 0% 1.00x ONLINE -Скопируйте какие-нибудь важные данные в пул для защиты от ошибок данных с использованием функции самовосстановления и создайте контрольную сумму пула для последующего сравнения.
# cp /some/important/data /healer
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
healer 960M 67.7M 892M - - 0% 7% 1.00x ONLINE -
# sha1 /healer > checksum.txt
# cat checksum.txt
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1fСимулируйте повреждение данных, записав случайные данные в начало одного из дисков в зеркале. Чтобы предотвратить восстановление данных ZFS при обнаружении, экспортируйте пул перед повреждением и снова импортируйте его после.
Это опасная операция, которая может уничтожить важные данные, и приведена здесь только для демонстрации. Не пытайтесь выполнить её во время нормальной работы хранилища данных. Также этот пример преднамеренного повреждения не должен выполняться на диске, содержащем файловую систему, не использующую ZFS на другом разделе. Не используйте имена дисковых устройств, кроме тех, что входят в пул. Убедитесь, что существуют резервные копии пула, и проверьте их перед выполнением команды! |
# zpool export healer
# dd if=/dev/random of=/dev/ada1p1 bs=1m count=200
200+0 records in
200+0 records out
209715200 bytes transferred in 62.992162 secs (3329227 bytes/sec)
# zpool import healerСтатус пула показывает, что на одном устройстве произошла ошибка. Обратите внимание, что приложения, читающие данные из пула, не получили некорректных данных. ZFS предоставил данные с устройства ada0p1 с правильными контрольными суммами. Чтобы найти устройство с неверной контрольной суммой, ищите то, у которого в столбце CKSUM указано ненулевое значение.
# zpool status healer
pool: healer
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
config:
NAME STATE READ WRITE CKSUM
healer ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 1
errors: No known data errorsZFS обнаружил ошибку и обработал её, используя избыточность на неповреждённом зеркальном диске ada0p1. Сравнение контрольных сумм с исходными покажет, восстановлена ли согласованность пула.
# sha1 /healer >> checksum.txt
# cat checksum.txt
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1fГенерируйте контрольные суммы до и после намеренного изменения данных, пока данные в пуле ещё совпадают. Это демонстрирует, как ZFS способен автоматически обнаруживать и исправлять любые ошибки, когда контрольные суммы различаются. Обратите внимание, что это возможно только при наличии достаточной избыточности в пуле. Пул, состоящий из одного устройства, не обладает возможностями самовосстановления. Именно поэтому контрольные суммы так важны в ZFS — не отключайте их ни по какой причине. ZFS не требует использования fsck(8) или аналогичной программы проверки целостности файловой системы для обнаружения и исправления ошибок, а также поддерживает доступность пула даже при наличии проблемы. Теперь требуется операция scrub для перезаписи поврежденных данных на ada1p1.
# zpool scrub healer
# zpool status healer
pool: healer
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
scan: scrub in progress since Sat Jul 11 10:34:02 2026
40.8M scanned at 20.4M/s, 24.9M issued at 12.4M/s, 67.0M total
9.63M repaired, 37.16% done, 00:00:03 to go
config:
NAME STATE READ WRITE CKSUM
healer ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 627 (repairing)
errors: No known data errorsОперация scrub читает данные с ada0p1 и перезаписывает любые данные с некорректной контрольной суммой на ada1p1, что отображается как (repairing) в выводе zpool status. После завершения операции состояние пула изменяется на:
# zpool status healer
pool: healer
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
scan: scrub repaired 66.5M in 00:00:06 with 0 errors on Sat Jul 11 10:34:08 2026
config:
NAME STATE READ WRITE CKSUM
healer ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 2.72K
errors: No known data errorsПосле завершения операции очистки, когда все данные синхронизированы с ada0p1 на ada1p1, сбросьте сообщения об ошибках из состояния пула, выполнив команду zpool clear, как описано в разделе Сброс состояния ошибки.
# zpool clear healer
# zpool status healer
pool: healer
state: ONLINE
scan: scrub repaired 66.5M in 00:00:06 with 0 errors on Sat Jul 11 10:34:08 2026
config:
NAME STATE READ WRITE CKSUM
healer ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
errors: No known data errorsПулу возвращено полностью рабочее состояние, все счётчики ошибок теперь обнулены.
23.3.14. TRIM и инициализация
Твердотельные накопители и тонко выделяемое хранилище работают лучше всего, когда ZFS сообщает им, какие блоки больше не используются. zpool trim передаёт эту информацию каждому устройству в пуле, которое поддерживает команды TRIM или UNMAP:
# zpool trim mypoolВыполните усечение одного устройства, указав его имя после пула, как в zpool trim mypool nda0p3. zpool trim -w ожидает завершения усечения, -c отменяет выполняющееся усечение, а -s приостанавливает его; повторный запуск zpool trim возобновляет приостановленное усечение. На устройствах, поддерживающих эту возможность, zpool trim --secure запрашивает безопасное усечение, при котором устройство гарантирует стирание данных, хранящихся на усечённых блоках.
zpool status -t показывает прогресс trim для каждого устройства:
# zpool status -t mypool
pool: mypool
state: ONLINE
scan: scrub repaired 0B in 00:12:33 with 0 errors on Sat Jul 11 03:31:11 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
nda0p3 ONLINE 0 0 0 (23% trimmed, started at Sat Jul 11 09:15:04 2026)
nda1p3 ONLINE 0 0 0 (22% trimmed, started at Sat Jul 11 09:15:04 2026)
errors: No known data errorsУстановка свойства пула autotrim в значение on заставляет ZFS непрерывно отправлять небольшие команды TRIM по мере освобождения пространства пулом:
# zpool set autotrim=on mypoolАвтоматическая утилизация пропускает небольшие освобожденные области и создает постоянную дополнительную нагрузку на устройства. Для большинства систем отключение autotrim и выполнение полной команды zpool trim по расписанию дает лучшие результаты. Начиная с FreeBSD 14.1 и более поздних версий, periodic(8) выполняет такую утилизацию ежедневно, если в /etc/periodic.conf содержится daily_trim_zfs_enable="YES".
zpool initialize является аналогом процедуры усечения: она записывает шаблон во всё нераспределённое пространство на указанных устройствах или на каждое подходящее устройство в пуле, если имена устройств не заданы. Это заставляет нижележащее хранилище выделить пространство заранее, избегая задержек при первой записи на тонко подготовленные виртуальные диски, а также проверяет новые устройства перед тем, как доверить им данные.
# zpool initialize mypoolКак и в случае с усечением, -c отменяет инициализацию, -s приостанавливает её, а -w ожидает её завершения; -u удаляет состояние инициализации с устройств. Подробнее см. zpool-trim(8) и zpool-initialize(8).
23.3.15. Контрольные точки пула
zpool checkpoint сохраняет состояние всего пула, включая каждый набор данных и конфигурацию пула, так что последующий откат возвращает пул к точному состоянию, которое он имел при создании контрольной точки. Создавайте контрольную точку перед рискованными административными операциями, такими как обновление операционной системы, включение новых функций пула или реорганизация наборов данных:
# zpool checkpoint mypoolПул может хранить не более одной контрольной точки одновременно. Столбец CKPOINT команды zpool list показывает, сколько места занимает контрольная точка по мере расхождения пула с сохранённым состоянием:
# zpool list mypool
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
mypool 4.50T 1.42T 3.08T 221M - 4% 31% 1.00x ONLINE -Чтобы откатить изменения, экспортируйте пул и импортируйте его снова с помощью --rewind-to-checkpoint:
# zpool export mypool
# zpool import --rewind-to-checkpoint mypoolПеремотка (rewinding) отбрасывает все изменения, внесенные в пул после создания контрольной точки, включая более новые снимки и изменения свойств. Удалите контрольную точку, которая больше не нужна, чтобы освободить занимаемое ею пространство; -w ожидает завершения удаления:
# zpool checkpoint -d -w mypoolПока существует контрольная точка, ZFS отказывает в операциях, изменяющих структуру пула: zpool remove, zpool attach, zpool detach, zpool split и zpool reguid. Пространство, освобожденное после создания контрольной точки, не возвращается, пока контрольная точка не будет удалена, поэтому долгоживущая контрольная точка на активном пуле может заполнить его.
Контрольная точка не является заменой приведенных в снимков или резервных копий. Она защищает от административных ошибок в течение короткого периода, располагается на тех же дисках, что и пул, а откат отбрасывает все, записанное после ее создания. |
См. zpool-checkpoint(8) для подробностей.
23.3.16. Увеличение размера пула
Наименьшее устройство в каждом vdev ограничивает полезный размер избыточного пула. Замените наименьшее устройство на устройство большего размера. После завершения операции замены или пересинхронизации пул может расшириться для использования ёмкости нового устройства. Например, рассмотрим зеркало из диска на 1 ТБ и диска на 2 ТБ. Полезное пространство составляет 1 ТБ. При замене диска на 1 ТБ другим диском на 2 ТБ процесс пересинхронизации копирует существующие данные на новый диск. Поскольку оба устройства теперь имеют ёмкость 2 ТБ, доступное пространство зеркала увеличивается до 2 ТБ.
Пул не использует новую ёмкость автоматически по умолчанию. Установите свойство пула autoexpand в значение on перед заменой устройств, и пул увеличится, как только последнее устройство меньшего размера покинет vdev:
# zpool set autoexpand=on mypoolИначе, начните расширение, используя zpool online -e для каждого устройства. После расширения всех устройств дополнительное пространство становится доступным для пула.
Чтобы увеличить размер vdev RAID-Z, добавив диск вместо замены существующих, см. Расширение RAID-Z.
23.3.17. Импорт и экспорт пулов
Экспортируйте пулы перед перемещением на другую систему. ZFS отмонтирует все наборы данных, помечая каждое устройство как экспортированное, но все ещё заблокированное, чтобы предотвратить использование другими дисками. Это позволяет импортировать пулы на других машинах, операционных системах с поддержкой ZFS и даже на аппаратных архитектурах другого типа (с некоторыми оговорками, см. zpool(8)). Если в наборе данных есть открытые файлы, используйте zpool export -f для принудительного экспорта пула. Используйте эту команду с осторожностью. Наборы данных будут принудительно отмонтированы, что может привести к неожиданному поведению приложений, работавших с открытыми файлами в этих наборах данных.
Экспортируйте пул, который не используется:
# zpool export mypoolИмпорт пула автоматически монтирует наборы данных. Если такое поведение нежелательно, используйте zpool import -N, чтобы предотвратить это. zpool import -o устанавливает временные свойства для данного конкретного импорта. zpool import -o altroot= позволяет импортировать пул с базовой точкой монтирования вместо корня файловой системы. Если пул последний раз использовался в другой системе и не был корректно экспортирован, принудительно импортируйте его с помощью zpool import -f. zpool import -a импортирует все пулы, которые, по-видимому, не используются другой системой.
zpool-import(8) также предоставляет опции для восстановления поврежденных пулов. zpool import -F пытается откатить пул к более ранней группе транзакций, когда последние повреждены, отбрасывая последние несколько секунд записей. zpool import -m позволяет импортировать пул, у которого отсутствует выделенное устройство журнала. zpool import -o readonly=on импортирует пул в режиме только для чтения, предотвращая все записи, что полезно для анализа последствий или при спасении данных из отказывающего пула. zpool import -R /mnt объединяет altroot=/mnt с cachefile=none, сохраняя спасательный импорт от нарушения путей монтирования и кэша пулов работающей системы.
Выведите список всех доступных пулов для импорта:
# zpool import
pool: mypool
id: 9930174748043525076
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
mypool ONLINE
ada0p1 ONLINEИмпортируйте пул с альтернативным корневым каталогом:
# zpool import -o altroot=/mnt mypool
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 110K 47.0G 31K /mnt/mypoolПри загрузке сценарии запуска ZFS, включённые через zfs_enable="YES" в /etc/rc.conf, импортируют каждый пул, записанный в /etc/zfs/zpool.cache. Импорт пула автоматически добавляет его в этот файл кэша; свойство пула cachefile управляет этим поведением. Пулы, импортированные с cachefile=none, не восстанавливаются автоматически после перезагрузки.
23.3.17.1. Импорт пула, зашифрованного GELI
Опция Encrypt Disks инсталлятора FreeBSD шифрует разделы пула с помощью geli(8), описанного в Шифрование разделов диска, а не с помощью собственного шифрования ZFS. На установленной системе загрузчик запрашивает парольную фразу и подключает провайдеров перед монтированием корневого пула, но сама ZFS ничего не знает о шифровании: при загрузке с аварийного носителя или переносе дисков на другой хост zpool import не находит пул, пока провайдеры GELI не будут подключены.
Присоедините зашифрованный freebsd-zfs раздел каждого диска в пуле, указав парольную фразу, затем импортируйте пул:
# geli attach ada0p4
Enter passphrase:
# zpool import -f -R /mnt zrootИспользуйте gpart show, чтобы определить разделы freebsd-zfs; при стандартной раскладке установщика зашифрованный раздел — это p4. Системы, установленные с устаревшей раскладкой, которая хранит отдельный незашифрованный загрузочный пул, дополнительно содержат файл ключа в /boot/encryption.key в этом пуле; подключите эти провайдеры с помощью geli attach -k /path/to/encryption.key.
23.3.18. Обновление пула дисков
После обновления FreeBSD или при импорте пула с системы, использующей более старую версию, вручную обновите пул, чтобы активировать поддержку новых функций. Перед обновлением учтите, может ли пул потребоваться для импорта на более старой системе. Обновление является необратимым процессом. Обновление старых пулов возможно, но понижение версии пулов с новыми функциями — нет.
Пулы больше не имеют единого номера версии. Вместо этого каждое изменение формата на диске представляет собой отдельный признак (feature flag), описанный в zpool-features(7). Признак включается (enabled), когда пул разрешает его использование, и становится активным (active), как только пул сохраняет данные, зависящие от него. Включённый, но неактивный признак не влияет на совместимость. Как только признак становится активным, программное обеспечение без его поддержки больше не может импортировать пул, хотя пулы, все активные признаки которых являются «совместимыми только для чтения», всё ещё допускают импорт в режиме только для чтения.
zpool status сообщает, когда поддерживаемые возможности не включены в пуле:
# zpool status mypool
pool: mypool
state: ONLINE
status: Some supported and requested features are not enabled on the pool.
The pool can still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
the pool may no longer be accessible by software that does not support
the features. See zpool-features(7) for details.
scan: scrub repaired 0B in 00:11:03 with 0 errors on Sat Jul 11 03:15:41 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p1 ONLINE 0 0 0
ada1p1 ONLINE 0 0 0
errors: No known data errorsВыполнение zpool upgrade без аргументов выводит список всех пулов с отключёнными возможностями:
# zpool upgrade
This system supports ZFS pool feature flags.
Some supported features are not enabled on the following pools. Once a
feature is enabled the pool may become incompatible with software
that does not support the feature. See zpool-features(7) for details.
Обратите внимание, что функция «совместимость» (compatibility) пула может использоваться для предотвращения
обновлений функциональных возможностей.
POOL FEATURE
---------------
mypool
zilsaxattr
head_errlog
blake3
block_cloning
vdev_zaps_v2Используйте zpool upgrade -v, чтобы вывести список всех функций, поддерживаемых работающей системой, вместе с устаревшими номерами версий. Включите все поддерживаемые функции в пуле:
# zpool upgrade mypool
This system supports ZFS pool feature flags.
Enabled the following features on 'mypool':
zilsaxattr
head_errlog
blake3
block_cloning
vdev_zaps_v2Пулы, которые должны оставаться импортируемыми на системах, работающих с более старым программным обеспечением ZFS, могут ограничивать, какие возможности zpool create и zpool upgrade включают, через свойство пула compatibility:
# zpool create -o compatibility=openzfs-2.1-freebsd mypool mirror /dev/ada0p1 /dev/ada1p1Установка свойства на существующем пуле с помощью zpool set также работает. Каждый именованный набор функций соответствует файлу в /usr/share/zfs/compatibility.d, и значение по умолчанию off позволяет использовать все функции. Установка свойства не отключает уже включённые функции.
Обновите загрузочный код на системах, которые загружаются с пула, чтобы поддержать новые свойства пула. Используйте Для загрузки в устаревшем режиме с использованием GPT используйте следующую команду: Для систем, использующих EFI для загрузки, выполните следующую команду: Данные инструкции применимы к системам amd64. В зависимости от архитектуры файл имеет другое имя. Обратитесь к uefi(8), чтобы узнать имена файлов, специфичных для конкретной архитектуры. Примените загрузочный код ко всем загрузочным дискам в пуле. Подробнее см. в gpart(8). |
23.3.19. Отображение записанной истории пулов
ZFS записывает команды, которые изменяют пул, включая создание наборов данных, изменение свойств или замену диска. Просмотр истории создания пула полезен, так же как и проверка того, какой пользователь выполнил конкретное действие и когда. История не хранится в файле журнала, а является частью самого пула. Команда для просмотра этой истории называется zpool history:
# zpool history
History for 'tank':
2026-07-11.10:24:05 zpool create tank mirror /dev/ada0p1 /dev/ada1p1
2026-07-11.18:50:58 zfs set atime=off tank
2026-07-11.18:51:09 zfs set checksum=fletcher4 tank
2026-07-11.18:51:18 zfs create tank/backupВывод показывает команды zpool и zfs, изменяющие пул каким-либо образом, вместе с временной меткой. Команды вроде zfs list не включаются. Если имя пула не указано, ZFS отображает историю всех пулов.
zpool history может отображать ещё больше информации при использовании опций -i или -l. Опция -i показывает события, инициированные пользователем, а также внутренние события ZFS, зарегистрированные в журнале.
# zpool history -i
History for 'tank':
2026-07-11.10:24:05 [txg:5] create pool version 5000; software version zfs-2.2.7-FreeBSD_gd75f9ee8b; uts myzfsbox 14.3-RELEASE 1403000 amd64
2026-07-11.18:50:53 [txg:50] set tank (21) atime=0
2026-07-11.18:50:58 zfs set atime=off tank
2026-07-11.18:51:04 [txg:53] set tank (21) checksum=7
2026-07-11.18:51:09 zfs set checksum=fletcher4 tank
2026-07-11.18:51:13 [txg:55] create tank/backup (39)
2026-07-11.18:51:18 zfs create tank/backupПоказать более подробную информацию, добавив -l. Отображение записей истории в длинном формате, включая такие сведения, как имя пользователя, выполнившего команду, и имя хоста, на котором произошло изменение.
# zpool history -l
History for 'tank':
2026-07-11.10:24:05 zpool create tank mirror /dev/ada0p1 /dev/ada1p1 [user 0 (root) on myzfsbox:global]
2026-07-11.18:50:58 zfs set atime=off tank [user 0 (root) on myzfsbox:global]
2026-07-11.18:51:09 zfs set checksum=fletcher4 tank [user 0 (root) on myzfsbox:global]
2026-07-11.18:51:18 zfs create tank/backup [user 0 (root) on myzfsbox:global]Вывод показывает, что пользователь root создал зеркальный пул с дисками /dev/ada0p1 и /dev/ada1p1. Также в каждой команде отображается имя хоста myzfsbox. Отображение имени хоста становится важным при экспорте пула с одной системы и импорте на другую. Можно различить команды, выполненные на другой системе, по имени хоста, записанному для каждой команды.
Объедините оба варианта с zpool history, чтобы получить максимально детальную информацию для любого заданного пула. История пула предоставляет ценную информацию при отслеживании выполненных действий или необходимости более детального вывода для отладки.
23.3.20. Мониторинг производительности
Встроенная система мониторинга может отображать статистику операций ввода-вывода пула в реальном времени. Она показывает объём свободного и занятого пространства в пуле, количество операций чтения и записи в секунду, а также используемую пропускную способность ввода-вывода. По умолчанию ZFS отслеживает и отображает все пулы в системе. Укажите имя пула, чтобы ограничить мониторинг только этим пулом. Простой пример:
# zpool iostat
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
data 288G 1.53T 2 11 11.3K 57.1KЧтобы непрерывно отслеживать активность ввода-вывода, укажите число в качестве последнего параметра, задающее интервал в секундах между обновлениями. Следующая строка статистики выводится после каждого интервала. Нажмите Ctrl+C, чтобы остановить непрерывный мониторинг. Укажите второе число в командной строке после интервала, чтобы задать общее количество отображаемой статистики.
Отображать более детальную статистику ввода-вывода с помощью -v. Каждое устройство в пуле отображается с отдельной строкой статистики. Это полезно для просмотра операций чтения и записи, выполняемых на каждом устройстве, и может помочь определить, замедляет ли какое-либо отдельное устройство работу пула. В этом примере показан зеркальный пул с двумя устройствами:
# zpool iostat -v
capacity operations bandwidth
pool alloc free read write read write
----------------------- ----- ----- ----- ----- ----- -----
data 288G 1.53T 2 12 9.23K 61.5K
mirror 288G 1.53T 2 12 9.23K 61.5K
ada1p1 - - 0 4 5.61K 61.7K
ada2p1 - - 1 4 5.04K 61.7K
----------------------- ----- ----- ----- ----- ----- -----zpool iostat предоставляет несколько более детальных представлений о конвейере ввода-вывода. -l (latency) добавляет столбцы со средней задержкой, разделяя общее время ожидания на время на диске и время, проведенное в различных очередях ввода-вывода. -q (queue) показывает количество ожидающих и активных операций в каждой очереди на vdev. -w выводит полные гистограммы задержек, а -r (request size) выводит гистограммы размеров запросов для каждого листового vdev.
Столбцы задержки в -l позволяют легко заметить один медленный диск, который замедляет работу всего vdev:
# zpool iostat -lv data
capacity operations bandwidth total_wait disk_wait syncq_wait asyncq_wait scrub trim rebuild
pool alloc free read write read write read write read write read write read write wait wait wait
---------- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -------
data 288G 1.53T 156 212 19.4M 26.6M 14ms 186ms 5ms 184ms 1us 2us 8ms 2ms - - -
mirror-0 288G 1.53T 156 212 19.4M 26.6M 14ms 186ms 5ms 184ms 1us 2us 8ms 2ms - - -
ada1p1 - - 79 106 9.7M 13.3M 3ms 5ms 3ms 4ms 1us 2us 1ms 1ms - - -
ada2p1 - - 77 106 9.7M 13.3M 212ms 187ms 208ms 183ms 1us 2us 15ms 3ms - - -
---------- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -------В этом примере ada2p1 требует сотни миллисекунд дискового времени для операций ввода-вывода, которые его зеркальный партнёр ada1p1 выполняет за однозначные миллисекунды, при этом оба обрабатывают схожее количество операций. Запись в зеркало завершается только после того, как завершится самый медленный участник, поэтому задержка записи всего vdev отслеживает ada2p1. Высокая задержка при нормальной работе, без ошибок чтения, записи или контрольных сумм в zpool status, часто указывает на диск, который выполняет внутренние повторы, и является кандидатом на замену.
Скрипты, которым необходимо дождаться завершения фоновой активности пула, могут блокироваться на zpool wait:
# zpool wait -t scrub,resilver mypoolКоманда возвращает управление, как только ни одно из указанных действий, таких как scrub, resilver, trim или remove, не выполняется. Полный список действий приведён в zpool-wait(8).
|
23.3.21. Разделение пула хранения данных
ZFS может разделить пул, состоящий из одного или нескольких зеркальных vdev, на два пула. Если не указано иное, ZFS отсоединяет последний элемент каждого зеркала и создаёт новый пул с теми же данными. Обязательно выполните пробный запуск операции с параметром -n сначала. Это отобразит детали запрошенной операции без её фактического выполнения. Это помогает убедиться, что операция выполнит то, что задумал пользователь.
23.4. Управление с помощью утилиты`zfs`
Утилита zfs позволяет создавать, удалять и управлять всеми существующими наборами данных ZFS в пределах пула. Для управления самим пулом используйте zpool.
23.4.1. Создание и удаление наборов данных
В отличие от традиционных дисков и менеджеров томов, пространство в ZFS не выделяется заранее. В традиционных файловых системах после разметки и выделения пространства невозможно добавить новую файловую систему без добавления нового диска. В ZFS создание новых файловых систем возможно в любое время. Каждый набор данных обладает свойствами, включая такие функции, как сжатие, дедупликация, кэширование и квоты, а также другие полезные свойства, такие как режим только для чтения, чувствительность к регистру, сетевое общее использование файлов и точка монтирования. Возможно вложение наборов данных друг в друга, при этом дочерние наборы данных наследуют свойства от своих родительских. Делегирование, репликация, снимки, клетки позволяют администрировать и уничтожать каждый набор данных как единое целое. Создание отдельного набора данных для каждого типа или группы файлов имеет свои преимущества. Недостатком наличия большого количества наборов данных является то, что некоторые команды, такие как zfs list, будут выполняться медленнее, а монтирование сотен или даже тысяч наборов данных замедлит процесс загрузки FreeBSD.
Создайте новый набор данных и включите для него сжатие LZ4:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 781M 93.2G 144K none
mypool/ROOT 777M 93.2G 144K none
mypool/ROOT/default 777M 93.2G 777M /
mypool/tmp 176K 93.2G 176K /tmp
mypool/usr 616K 93.2G 144K /usr
mypool/usr/home 184K 93.2G 184K /usr/home
mypool/usr/ports 144K 93.2G 144K /usr/ports
mypool/usr/src 144K 93.2G 144K /usr/src
mypool/var 1.20M 93.2G 608K /var
mypool/var/crash 148K 93.2G 148K /var/crash
mypool/var/log 178K 93.2G 178K /var/log
mypool/var/mail 144K 93.2G 144K /var/mail
mypool/var/tmp 152K 93.2G 152K /var/tmp
# zfs create -o compress=lz4 mypool/usr/mydataset
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 781M 93.2G 144K none
mypool/ROOT 777M 93.2G 144K none
mypool/ROOT/default 777M 93.2G 777M /
mypool/tmp 176K 93.2G 176K /tmp
mypool/usr 704K 93.2G 144K /usr
mypool/usr/home 184K 93.2G 184K /usr/home
mypool/usr/mydataset 87.5K 93.2G 87.5K /usr/mydataset
mypool/usr/ports 144K 93.2G 144K /usr/ports
mypool/usr/src 144K 93.2G 144K /usr/src
mypool/var 1.20M 93.2G 610K /var
mypool/var/crash 148K 93.2G 148K /var/crash
mypool/var/log 178K 93.2G 178K /var/log
mypool/var/mail 144K 93.2G 144K /var/mail
mypool/var/tmp 152K 93.2G 152K /var/tmpУничтожение набора данных выполняется гораздо быстрее, чем удаление файлов в наборе данных, так как не требует сканирования файлов и обновления соответствующих метаданных.
Уничтожьте созданный набор данных:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 880M 93.1G 144K none
mypool/ROOT 777M 93.1G 144K none
mypool/ROOT/default 777M 93.1G 777M /
mypool/tmp 176K 93.1G 176K /tmp
mypool/usr 101M 93.1G 144K /usr
mypool/usr/home 184K 93.1G 184K /usr/home
mypool/usr/mydataset 100M 93.1G 100M /usr/mydataset
mypool/usr/ports 144K 93.1G 144K /usr/ports
mypool/usr/src 144K 93.1G 144K /usr/src
mypool/var 1.20M 93.1G 610K /var
mypool/var/crash 148K 93.1G 148K /var/crash
mypool/var/log 178K 93.1G 178K /var/log
mypool/var/mail 144K 93.1G 144K /var/mail
mypool/var/tmp 152K 93.1G 152K /var/tmp
# zfs destroy mypool/usr/mydataset
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 781M 93.2G 144K none
mypool/ROOT 777M 93.2G 144K none
mypool/ROOT/default 777M 93.2G 777M /
mypool/tmp 176K 93.2G 176K /tmp
mypool/usr 616K 93.2G 144K /usr
mypool/usr/home 184K 93.2G 184K /usr/home
mypool/usr/ports 144K 93.2G 144K /usr/ports
mypool/usr/src 144K 93.2G 144K /usr/src
mypool/var 1.21M 93.2G 612K /var
mypool/var/crash 148K 93.2G 148K /var/crash
mypool/var/log 178K 93.2G 178K /var/log
mypool/var/mail 144K 93.2G 144K /var/mail
mypool/var/tmp 152K 93.2G 152K /var/tmpВ современных версиях ZFS команда zfs destroy выполняется асинхронно, и освобождённое пространство может появиться в пуле только через несколько минут. Используйте команду zpool get freeing poolname для просмотра свойства freeing, которое показывает, сколько места ещё остаётся освободить в фоновом режиме. Используйте команду zpool wait -t free poolname, чтобы дождаться завершения фонового освобождения. Если существуют дочерние наборы данных, например снимки или другие наборы данных, уничтожение родительского набора невозможно. Для удаления набора данных и его дочерних элементов используйте -r, чтобы рекурсивно удалить набор данных и его потомков. Опция -n -v позволяет вывести список наборов данных и снимков, которые будут удалены данной операцией, без фактического выполнения удаления. Также отображается пространство, которое будет освобождено после удаления снимков.
23.4.2. Создание и удаление томов
Том — это особый тип набора данных. Вместо монтирования в качестве файловой системы он представляется как блочное устройство в /dev/zvol/имя_пула/набор_данных. Это позволяет использовать том для других файловых систем, в качестве дисков для виртуальной машины или сделать его доступным для других сетевых узлов с использованием таких протоколов, как iSCSI или HAST.
Отформатируйте том с любой файловой системой или без файловой системы для хранения сырых данных. Для пользователя том выглядит как обычный диск. Размещение обычных файловых систем на этих zvols предоставляет возможности, которых нет у обычных дисков или файловых систем. Например, использование свойства сжатия на томе объёмом 250 МБ позволяет создать сжатую файловую систему FAT.
# zfs create -V 250m -o compression=on tank/fat32
# zfs list tank
NAME USED AVAIL REFER MOUNTPOINT
tank 258M 670M 31K /tank
# newfs_msdos -F32 /dev/zvol/tank/fat32
# mount -t msdosfs /dev/zvol/tank/fat32 /mnt
# df -h /mnt | grep fat32
Filesystem Size Used Avail Capacity Mounted on
/dev/zvol/tank/fat32 249M 24k 249M 0% /mnt
# mount | grep fat32
/dev/zvol/tank/fat32 on /mnt (msdosfs, local)Создание тома резервирует в пуле достаточно места для хранения полного размера тома. Чтобы пропустить это резервирование, создайте разреженный том (sparse volume), также известный как тонко выделенный том, с помощью -s:
# zfs create -s -V 250g tank/bigdiskРазреженные тома позволяют выделять больше пространства, чем фактически имеется в пуле. Записи в разреженный том могут завершиться ошибкой ENOSPC, когда в пуле заканчивается место, поэтому используйте разреженные тома только там, где потребитель тома допускает ошибки записи.
Свойство volmode управляет тем, как ZFS предоставляет том операционной системе. Установка значения full предоставляет том как провайдер GEOM с максимальной функциональностью, а geom является псевдонимом для full. Установка значения dev предоставляет том как обычный узел устройства, скрывая любые разделы, которые он содержит. Тома с volmode, установленным в none, не предоставляются за пределами ZFS вообще, но по-прежнему поддерживают снимки, клоны и репликацию, что делает их полезными в качестве целей репликации. Свойство по умолчанию имеет значение default, которое откладывается на системную настройку zvol_volmode, описанную в zfs(4).
Тома хорошо работают в качестве виртуальных дисков для виртуальных машин bhyve(8) и как хранилище для экстентов iSCSI: объявите устройство тома как LUN в ctl.conf(5) и обслуживайте его с помощью ctld(8).
Не размещайте пространство подкачки на томах ZFS. Когда в системе недостаточно памяти, сам ZFS нуждается в памяти для завершения записи, которая освободила бы память, и система может зависнуть. Подробности см. в upstream-проблеме OpenZFS openzfs/zfs#7734. Вместо этого используйте выделенный раздел подкачки. |
Уничтожение тома во многом аналогично уничтожению обычного набора данных файловой системы. Операция выполняется почти мгновенно, но освобождение места может занять несколько минут и происходит в фоновом режиме.
23.4.3. Переименование набора данных
Для изменения имени набора данных используйте zfs rename. Эту же команду можно использовать для изменения родительского набора данных. Переименование набора данных с изменением родительского набора приведёт к изменению значений свойств, унаследованных от родительского набора данных. Переименование набора данных размонтирует, а затем снова смонтирует его в новом месте (с учётом наследования от нового родительского набора данных). Чтобы предотвратить это поведение, используйте опцию -u.
Переименовать набор данных и переместить его под другой родительский набор данных:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 780M 93.2G 144K none
mypool/ROOT 777M 93.2G 144K none
mypool/ROOT/default 777M 93.2G 777M /
mypool/tmp 176K 93.2G 176K /tmp
mypool/usr 704K 93.2G 144K /usr
mypool/usr/home 184K 93.2G 184K /usr/home
mypool/usr/mydataset 87.5K 93.2G 87.5K /usr/mydataset
mypool/usr/ports 144K 93.2G 144K /usr/ports
mypool/usr/src 144K 93.2G 144K /usr/src
mypool/var 1.21M 93.2G 614K /var
mypool/var/crash 148K 93.2G 148K /var/crash
mypool/var/log 178K 93.2G 178K /var/log
mypool/var/mail 144K 93.2G 144K /var/mail
mypool/var/tmp 152K 93.2G 152K /var/tmp
# zfs rename mypool/usr/mydataset mypool/var/newname
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 780M 93.2G 144K none
mypool/ROOT 777M 93.2G 144K none
mypool/ROOT/default 777M 93.2G 777M /
mypool/tmp 176K 93.2G 176K /tmp
mypool/usr 616K 93.2G 144K /usr
mypool/usr/home 184K 93.2G 184K /usr/home
mypool/usr/ports 144K 93.2G 144K /usr/ports
mypool/usr/src 144K 93.2G 144K /usr/src
mypool/var 1.29M 93.2G 614K /var
mypool/var/crash 148K 93.2G 148K /var/crash
mypool/var/log 178K 93.2G 178K /var/log
mypool/var/mail 144K 93.2G 144K /var/mail
mypool/var/newname 87.5K 93.2G 87.5K /var/newname
mypool/var/tmp 152K 93.2G 152K /var/tmpПереименование снимков выполняется той же командой. Из-за особенностей снимков, их переименование не может изменить родительский набор данных. Для рекурсивного переименования снимка укажите -r; это также переименует все снимки с таким же именем в дочерних наборах данных.
# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
mypool/var/newname@first_snapshot 0 - 87.5K -
# zfs rename mypool/var/newname@first_snapshot new_snapshot_name
# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
mypool/var/newname@new_snapshot_name 0 - 87.5K -23.4.4. Установка свойств наборов данных
Каждый набор данных ZFS имеет свойства, которые определяют его поведение. Большинство свойств автоматически наследуются от родительского набора данных, но могут быть переопределены локально. Установите свойство для набора данных с помощью zfs set свойство=значение набор_данных. Большинство свойств имеют ограниченный набор допустимых значений, zfs get отобразит каждое возможное свойство и допустимые значения. Использование zfs inherit возвращает большинство свойств к их унаследованным значениям. Также возможны пользовательские свойства. Они становятся частью конфигурации набора данных и предоставляют дополнительную информацию о наборе данных или его содержимом. Чтобы отличить эти пользовательские свойства от встроенных в ZFS, используйте двоеточие (:), чтобы создать пользовательское пространство имён для свойства.
# zfs set custom:costcenter=1234 tank
# zfs get custom:costcenter tank
NAME PROPERTY VALUE SOURCE
tank custom:costcenter 1234 localЧтобы удалить пользовательское свойство, используйте zfs inherit с параметром -r. Если пользовательское свойство не определено ни в одном из родительских наборов данных, эта опция удаляет его (но история пула всё равно сохраняет запись об изменении).
# zfs inherit -r custom:costcenter tank
# zfs get custom:costcenter tank
NAME PROPERTY VALUE SOURCE
tank custom:costcenter - -
# zfs get all tank | grep custom:costcenter
#23.4.4.1. Получение и установка свойств общего доступа
Два часто используемых и полезных свойства наборов данных — это параметры общего доступа NFS и SMB. Их установка определяет, экспортируются ли наборы данных ZFS в сеть и каким образом. Во FreeBSD ZFS интегрируется с NFS-сервером в базовой системе: установка свойства sharenfs экспортирует набор данных через mountd(8). ZFS записывает запись экспорта в /etc/zfs/exports, которую mountd(8) читает в дополнение к /etc/exports. Для общего доступа к наборам данных требуется включенный NFS-сервер в /etc/rc.conf:
zfs_enable="YES" nfs_server_enable="YES"
Значение sharenfs может быть on, off или списком параметров exports(5), применяемых к экспорту.
Чтобы получить текущее состояние общего каталога, введите:
# zfs get sharenfs mypool/usr/home
NAME PROPERTY VALUE SOURCE
mypool/usr/home sharenfs on localЧтобы включить общий доступ к набору данных, введите:
# zfs set sharenfs=on mypool/usr/homeУстановите другие параметры для общего доступа к наборам данных через NFS, такие как -alldirs, -maproot и -network. Чтобы задать параметры для набора данных, доступного через NFS, введите:
# zfs set sharenfs="-alldirs,-maproot=root,-network=192.168.1.0/24" mypool/usr/homeСвойство sharesmb не работает во FreeBSD, так как библиотека совместного доступа реализует только NFS. Чтобы предоставить набор данных по SMB, установите пакет, например net/samba422, и укажите путь смонтированного набора данных в его конфигурации.
23.4.5. NFSv4 ACL
ZFS во FreeBSD хранит ACL в стиле NFSv4 нативно; свойство набора данных acltype по умолчанию имеет значение nfsv4. Каждый файл и каталог может нести список управления доступом наряду с традиционными битами разрешений, обеспечивая более тонкий контроль, чем модель владелец/группа/остальные. Отображайте и редактируйте эти списки с помощью getfacl(1) и setfacl(1).
Отобразить ACL файла:
% getfacl /usr/home/alice/notes.txt
# file: /usr/home/alice/notes.txt
# owner: alice
# group: alice
owner@:rw-p--aARWcCos:-------:allow
group@:r-----a-R-c--s:-------:allow
everyone@:r-----a-R-c--s:-------:allowПредоставьте дополнительному пользователю доступ на запись, добавив запись allow:
% setfacl -m u:bob:rwp::allow /usr/home/alice/notes.txtДва свойства наборов данных управляют тем, как ACL взаимодействуют с традиционной обработкой разрешений. Свойство aclmode (discard, groupmask, passthrough или restricted) определяет, что происходит с ACL, когда chmod(1) изменяет биты разрешений файла. При значении по умолчанию, discard, chmod удаляет все записи ACL, которые не представляют новый режим файла. Свойство aclinherit (discard, noallow, restricted, passthrough или passthrough-x) определяет, какие записи ACL новые файлы и каталоги наследуют от родительского каталога. При значении по умолчанию, restricted, унаследованные записи теряют разрешения write_acl и write_owner.
Смотрите setfacl(1) и zfsprops(7) для полного синтаксиса записей и описаний свойств.
23.4.6. Управление снимками
Снимки — одна из самых мощных функций ZFS. Снимок предоставляет доступную только для чтения копию набора данных на определённый момент времени. Благодаря механизму Copy-On-Write (COW), ZFS быстро создаёт снимки, сохраняя старые версии данных на диске. Если снимков не существует, ZFS освобождает место для последующего использования при перезаписи или удалении данных. Снимки экономят дисковое пространство, записывая только различия между текущим набором данных и предыдущей версией. Создание снимков возможно для целых наборов данных, но не для отдельных файлов или каталогов. Снимок набора данных дублирует всё его содержимое. Это включает свойства файловой системы, файлы, каталоги, права доступа и так далее. Снимки не занимают дополнительного места при создании, но начинают потреблять пространство по мере изменения блоков, на которые они ссылаются. Рекурсивные снимки, созданные с помощью -r, формируют снимки с одинаковыми именами для набора данных и его дочерних элементов, обеспечивая согласованный снимок файловых систем на определённый момент времени. Это может быть важно, когда приложение использует файлы в связанных наборах данных или зависящие друг от друга. Без снимков резервная копия содержала бы файлы из разных моментов времени.
Снимки в ZFS предоставляют множество функций, которых нет даже в других файловых системах с поддержкой снимков. Типичный пример использования снимков — быстрое резервное копирование текущего состояния файловой системы перед выполнением рискованных действий, таких как установка программного обеспечения или обновление системы. Если действие завершится неудачей, откат к снимку вернёт систему в состояние на момент его создания. Если обновление прошло успешно, снимок можно удалить для освобождения места. Без снимков неудачное обновление часто требует восстановления из резервных копий, что утомительно, отнимает много времени и может привести к простою системы, в течение которого она будет недоступна. Откат к снимкам выполняется быстро, даже во время обычной работы системы, с минимальным или нулевым временем простоя. Экономия времени огромна, особенно для многотерабайтных систем хранения, учитывая время, необходимое для копирования данных из резервной копии. Снимки не заменяют полное резервное копирование пула, но предлагают быстрый и простой способ сохранить копию набора данных на определённый момент времени.
23.4.6.1. Создание снимков
Для создания снимков используйте zfs snapshot наборданных@имяснимка. Добавление опции -r создаёт снимок рекурсивно с тем же именем для всех дочерних наборов данных.
Создать рекурсивный снимок всего пула:
# zfs list -t all
NAME USED AVAIL REFER MOUNTPOINT
mypool 780M 93.2G 144K none
mypool/ROOT 777M 93.2G 144K none
mypool/ROOT/default 777M 93.2G 777M /
mypool/tmp 176K 93.2G 176K /tmp
mypool/usr 616K 93.2G 144K /usr
mypool/usr/home 184K 93.2G 184K /usr/home
mypool/usr/ports 144K 93.2G 144K /usr/ports
mypool/usr/src 144K 93.2G 144K /usr/src
mypool/var 1.29M 93.2G 616K /var
mypool/var/crash 148K 93.2G 148K /var/crash
mypool/var/log 178K 93.2G 178K /var/log
mypool/var/mail 144K 93.2G 144K /var/mail
mypool/var/newname 87.5K 93.2G 87.5K /var/newname
mypool/var/newname@new_snapshot_name 0 - 87.5K -
mypool/var/tmp 152K 93.2G 152K /var/tmp
# zfs snapshot -r mypool@my_recursive_snapshot
# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
mypool@my_recursive_snapshot 0 - 144K -
mypool/ROOT@my_recursive_snapshot 0 - 144K -
mypool/ROOT/default@my_recursive_snapshot 0 - 777M -
mypool/tmp@my_recursive_snapshot 0 - 176K -
mypool/usr@my_recursive_snapshot 0 - 144K -
mypool/usr/home@my_recursive_snapshot 0 - 184K -
mypool/usr/ports@my_recursive_snapshot 0 - 144K -
mypool/usr/src@my_recursive_snapshot 0 - 144K -
mypool/var@my_recursive_snapshot 0 - 616K -
mypool/var/crash@my_recursive_snapshot 0 - 148K -
mypool/var/log@my_recursive_snapshot 0 - 178K -
mypool/var/mail@my_recursive_snapshot 0 - 144K -
mypool/var/newname@new_snapshot_name 0 - 87.5K -
mypool/var/newname@my_recursive_snapshot 0 - 87.5K -
mypool/var/tmp@my_recursive_snapshot 0 - 152K -Снимки не отображаются при обычной операции zfs list. Для вывода списка снимков добавьте -t snapshot к команде zfs list. Опция -t all показывает как файловые системы, так и снимки.
Снимки не монтируются напрямую, поэтому в столбце MOUNTPOINT не отображается путь. ZFS не указывает доступное дисковое пространство в столбце AVAIL, так как снимки доступны только для чтения после их создания. Сравните снимок с исходным набором данных:
# zfs list -rt all mypool/usr/home
NAME USED AVAIL REFER MOUNTPOINT
mypool/usr/home 184K 93.2G 184K /usr/home
mypool/usr/home@my_recursive_snapshot 0 - 184K -Отображение набора данных и снимка вместе показывает, как снимки работают в стиле COW. Они сохраняют внесённые изменения (дельту), а не полное содержимое файловой системы заново. Это означает, что снимки занимают мало места при внесении изменений. Наблюдайте за использованием пространства ещё внимательнее, скопировав файл в набор данных, а затем создав второй снимок:
# cp /etc/passwd /var/tmp
# zfs snapshot mypool/var/tmp@after_cp
# zfs list -rt all mypool/var/tmp
NAME USED AVAIL REFER MOUNTPOINT
mypool/var/tmp 206K 93.2G 118K /var/tmp
mypool/var/tmp@my_recursive_snapshot 88K - 152K -
mypool/var/tmp@after_cp 0 - 118K -Второй снимок содержит изменения в наборе данных после операции копирования. Это обеспечивает значительную экономию пространства. Обратите внимание, что размер снимка mypool/var/tmp@my_recursive_snapshot также изменился в столбце USED, показывая разницу между ним и последующим снимком.
23.4.6.2. Сравнение снимков
ZFS предоставляет встроенную команду для сравнения различий в содержимом между двумя снимками. Это полезно при наличии множества снимков, сделанных за определённый период, когда пользователь хочет увидеть, как файловая система изменялась со временем. Например, zfs diff позволяет пользователю найти последний снимок, который ещё содержит случайно удалённый файл. Применение этой команды к двум снимкам, созданным в предыдущем разделе, даёт следующий вывод:
# zfs list -rt all mypool/var/tmp
NAME USED AVAIL REFER MOUNTPOINT
mypool/var/tmp 206K 93.2G 118K /var/tmp
mypool/var/tmp@my_recursive_snapshot 88K - 152K -
mypool/var/tmp@after_cp 0 - 118K -
# zfs diff mypool/var/tmp@my_recursive_snapshot
M /var/tmp/
+ /var/tmp/passwdКоманда выводит список изменений между указанным снимком (в данном случае mypool/var/tmp@my_recursive_snapshot) и активной файловой системой. Первый столбец показывает тип изменения:
+ | Добавление пути или файла. |
- | Удаление пути или файла. |
M | Изменение пути или файла. |
R | Переименование пути или файла. |
Сравнивая вывод с таблицей, становится ясно, что ZFS добавил passwd после создания снимка mypool/var/tmp@my_recursive_snapshot. Это также привело к изменению родительского каталога, смонтированного в /var/tmp.
Сравнение двух снимков полезно при использовании функции репликации ZFS для передачи набора данных на другой хост в целях резервного копирования.
Сравните два снимка, указав полное имя набора данных и имя снимка для обоих наборов:
# cp /var/tmp/passwd /var/tmp/passwd.copy
# zfs snapshot mypool/var/tmp@diff_snapshot
# zfs diff mypool/var/tmp@my_recursive_snapshot mypool/var/tmp@diff_snapshot
M /var/tmp/
+ /var/tmp/passwd
+ /var/tmp/passwd.copy
# zfs diff mypool/var/tmp@my_recursive_snapshot mypool/var/tmp@after_cp
M /var/tmp/
+ /var/tmp/passwdАдминистратор резервного копирования может сравнить два снимка, полученных от отправляющего хоста, и определить фактические изменения в наборе данных. Дополнительную информацию см. в разделе Репликация.
23.4.6.3. Откат снимка состояния (Snapshot Rollback)
Когда доступен хотя бы один снимок, можно в любой момент к нему вернуться. Чаще всего это необходимо, когда текущее состояние набора данных больше не является корректным или требуется более старая версия. Такие ситуации, как неудачные локальные тесты разработки, неудачные обновления системы, нарушающие её функциональность, или необходимость восстановления удалённых файлов или каталогов, встречаются довольно часто. Для возврата к снимку используйте команду zfs rollback имя_снимка. Если изменений много, операция займёт значительное время. В течение этого времени набор данных всегда остаётся в согласованном состоянии, подобно тому, как база данных, соответствующая принципам ACID, выполняет откат. Это происходит, пока набор данных находится в рабочем состоянии и доступен без необходимости простоя. После отката к снимку набор данных возвращается в то же состояние, в котором он находился на момент создания снимка. Откат к снимку удаляет все другие данные в наборе, не входящие в снимок. Создание снимка текущего состояния набора данных перед откатом к предыдущему — хорошая практика, если некоторые данные могут потребоваться позже. Таким образом, пользователь может переключаться между снимками, не теряя ценные данные.
В первом примере выполняется откат к снимку, потому что неосторожная операция rm удалила больше данных, чем планировалось.
# zfs list -rt all mypool/var/tmp
NAME USED AVAIL REFER MOUNTPOINT
mypool/var/tmp 262K 93.2G 120K /var/tmp
mypool/var/tmp@my_recursive_snapshot 88K - 152K -
mypool/var/tmp@after_cp 53.5K - 118K -
mypool/var/tmp@diff_snapshot 0 - 120K -
# ls /var/tmp
passwd passwd.copy vi.recover
# rm /var/tmp/passwd*
# ls /var/tmp
vi.recoverНа этом этапе пользователь замечает удаление лишних файлов и хочет вернуть их обратно. ZFS предоставляет простой способ восстановления с использованием отката, если регулярно создаются снимки важных данных. Чтобы вернуть файлы и начать заново с последнего снимка, выполните команду:
# zfs rollback mypool/var/tmp@diff_snapshot
# ls /var/tmp
passwd passwd.copy vi.recoverОперация отката восстановила набор данных до состояния последнего снимка. Также возможен откат к более раннему снимку, если после него были созданы другие снимки. При попытке выполнить это действие ZFS выдаст следующее предупреждение:
# zfs list -rt snapshot mypool/var/tmp
NAME USED AVAIL REFER MOUNTPOINT
mypool/var/tmp@my_recursive_snapshot 88K - 152K -
mypool/var/tmp@after_cp 53.5K - 118K -
mypool/var/tmp@diff_snapshot 0 - 120K -
# zfs rollback mypool/var/tmp@my_recursive_snapshot
cannot rollback to 'mypool/var/tmp@my_recursive_snapshot': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
mypool/var/tmp@after_cp
mypool/var/tmp@diff_snapshotЭто предупреждение означает, что между текущим состоянием набора данных и снимком, к которому пользователь хочет выполнить откат, существуют другие снимки. Для завершения отката удалите эти снимки. ZFS не может отслеживать все изменения между различными состояниями набора данных, поскольку снимки доступны только для чтения. ZFS не удалит затронутые снимки, если пользователь явно не укажет параметр -r, подтверждая, что это желаемое действие. Если это действительно требуется, и вы осознаёте последствия потери всех промежуточных снимков, выполните команду:
# zfs rollback -r mypool/var/tmp@my_recursive_snapshot
# zfs list -rt snapshot mypool/var/tmp
NAME USED AVAIL REFER MOUNTPOINT
mypool/var/tmp@my_recursive_snapshot 8K - 152K -
# ls /var/tmp
vi.recoverВывод команды zfs list -t snapshot подтверждает удаление промежуточных снимков в результате выполнения zfs rollback -r.
23.4.6.4. Восстановление отдельных файлов из снимков
Снимки хранятся в скрытом каталоге родительского набора данных: .zfs/snapshot/имя_снимка. По умолчанию эти каталоги не отображаются даже при выполнении стандартной команды ls -a. Несмотря на то, что каталог не виден, доступ к нему осуществляется как к обычному каталогу. Свойство snapdir определяет, будут ли эти скрытые каталоги отображаться в списке содержимого каталога. Установка свойства в значение visible позволяет им появляться в выводе команды ls и других команд, работающих с содержимым каталогов.
# zfs get snapdir mypool/var/tmp
NAME PROPERTY VALUE SOURCE
mypool/var/tmp snapdir hidden default
# ls -a /var/tmp
. .. passwd vi.recover
# zfs set snapdir=visible mypool/var/tmp
# ls -a /var/tmp
. .. .zfs passwd vi.recoverВосстановите отдельные файлы в предыдущее состояние, скопировав их из снимка обратно в родительский набор данных. Структура каталогов в .zfs/snapshot содержит каталоги с именами, соответствующими ранее созданным снимкам, что упрощает их идентификацию. В следующем примере показано, как восстановить файл из скрытого каталога .zfs, скопировав его из снимка, содержащего последнюю версию файла:
# rm /var/tmp/passwd
# ls -a /var/tmp
. .. .zfs vi.recover
# ls /var/tmp/.zfs/snapshot
after_cp my_recursive_snapshot
# ls /var/tmp/.zfs/snapshot/after_cp
passwd vi.recover
# cp /var/tmp/.zfs/snapshot/after_cp/passwd /var/tmpДаже если свойство snapdir установлено в hidden, выполнение команды ls .zfs/snapshot всё равно покажет содержимое этого каталога. Администратор решает, отображать ли эти каталоги. Это настройка для каждого набора данных. Копирование файлов или каталогов из скрытого .zfs/snapshot достаточно просто. Попытка сделать наоборот приведёт к такой ошибке:
# cp /etc/rc.conf /var/tmp/.zfs/snapshot/after_cp/
cp: /var/tmp/.zfs/snapshot/after_cp/rc.conf: Read-only file systemОшибка напоминает пользователю, что снимки доступны только для чтения и не могут изменяться после создания. Копирование файлов в каталоги снимков и их удаление оттуда запрещены, так как это изменило бы состояние набора данных, который они представляют.
Снимки занимают место в зависимости от того, насколько родительская файловая система изменилась с момента создания снимка. Свойство used снимка отслеживает используемое им пространство. Его свойство written показывает, какой объём данных был записан на диск между предыдущим и текущим снимком.
Для удаления снимков и освобождения пространства используйте zfs destroy набор_данных@снимок. Добавление -r рекурсивно удаляет все снимки с таким же именем в родительском наборе данных. Добавление -n -v к команде выводит список снимков, которые будут удалены, и оценку освобождаемого пространства без фактического выполнения операции удаления.
23.4.6.5. Удержания снимков
Удержание (hold, hold) помечает снимок пользовательским тегом и предотвращает его уничтожение. Попытки уничтожить удерживаемый снимок с помощью zfs destroy завершаются ошибкой EBUSY. Снимок может иметь любое количество удержаний, каждое из которых идентифицируется уникальным именем тега. Удержания защищают снимки, которые всё ещё используются другими процессами, например, самый последний снимок, общий для обеих сторон цепочки репликации (см. Репликация). Случайное уничтожение этого общего снимка приводит к тому, что следующая репликация должна будет начинаться с полного потока (full stream).
Установите удержание с помощью zfs hold tag snapshot. Добавление -r также устанавливает удержания на снимки с тем же именем во всех дочерних наборах данных.
# zfs hold keepme mypool/var/tmp@my_recursive_snapshot
# zfs destroy mypool/var/tmp@my_recursive_snapshot
cannot destroy snapshot mypool/var/tmp@my_recursive_snapshot: dataset is busyzfs holds выводит список удержаний на снимке, показывая имя тега и время установки каждого удержания:
# zfs holds mypool/var/tmp@my_recursive_snapshot
NAME TAG TIMESTAMP
mypool/var/tmp@my_recursive_snapshot keepme Sat Jul 11 09:41 2026Снимите удержание с помощью zfs release. Уничтожение снимка снова становится возможным, как только снимается последнее удержание на нём:
# zfs release keepme mypool/var/tmp@my_recursive_snapshot
# zfs destroy mypool/var/tmp@my_recursive_snapshotСм. zfs-hold(8) для получения дополнительной информации.
23.4.7. Закладки
Перекрестная ссылка: zfs[zfs-term-bookmark,закладка] фиксирует момент времени, в который был создан снимок, без сохранения каких-либо данных снимка. Закладки почти не занимают места на диске, независимо от того, насколько изменится набор данных впоследствии. Как и снимок, закладка может служить источником инкрементальных данных для zfs send. В отличие от снимка, она не препятствует ZFS освобождать старые данные. Такое сочетание делает закладки полезными для инкрементальной репликации: после отправки снимка на другой пул создайте закладку на нем и уничтожьте его на отправляющей стороне, освобождая место, в то время как принимающая сторона сохраняет свою копию снимка. Смотрите раздел Инкрементальные резервные копии для описания самого процесса репликации.
Создайте закладку из снимка с помощью zfs bookmark. В именах закладок в качестве разделителя между именем набора данных и именем закладки используется #, так же как в именах снимков используется @.
# zfs snapshot mypool/data@snap1
# zfs send mypool/data@snap1 | zfs receive backup/data
# zfs bookmark mypool/data@snap1 mypool/data#snap1bm
# zfs destroy mypool/data@snap1Перечислите закладки с помощью zfs list -t bookmark:
# zfs list -t bookmark mypool/data
NAME USED AVAIL REFER MOUNTPOINT
mypool/data#snap1bm - - 184K -Когда наступает время для следующего инкрементального резервного копирования, создайте новый снимок и используйте закладку в качестве инкрементального источника:
# zfs snapshot mypool/data@snap2
# zfs send -i mypool/data#snap1bm mypool/data@snap2 | zfs receive backup/dataЭто работает, поскольку принимающий пул всё ещё имеет снапшот backup/data@snap1, соответствующий закладке. Закладки служат только в качестве источников для инкрементального резервирования. Смонтировать закладку, выполнить откат к ней или восстановить файлы из неё невозможно, так как она не содержит данных. Дополнительную информацию см. в zfs-bookmark(8).
23.4.8. Управление клонами
Клон — это копия снимка, которая рассматривается как обычный набор данных. В отличие от снимка, клон доступен для записи, может быть смонтирован и имеет свои собственные свойства. После создания клона с помощью команды zfs clone уничтожение исходного снимка становится невозможным. Чтобы изменить отношение «родитель-потомок» между клоном и снимком, используйте команду zfs promote. Продвижение клона делает снимок потомком клона, а не исходного родительского набора данных. Это изменит способ учёта пространства в ZFS, но не повлияет на фактически используемый объём. Клон можно смонтировать в любом месте иерархии файловой системы ZFS, а не только ниже исходного расположения снимка.
Чтобы продемонстрировать функцию клонирования, используйте следующий набора данных в качестве примера:
# zfs list -rt all camino/home/joe
NAME USED AVAIL REFER MOUNTPOINT
camino/home/joe 108K 1.3G 87K /usr/home/joe
camino/home/joe@plans 21K - 85.5K -
camino/home/joe@backup 0K - 87K -Типичное применение клонов — эксперименты с определённым набором данных, при этом снимок остаётся в качестве резервной копии на случай возникновения проблем. Поскольку снимки нельзя изменить, создаётся доступный для чтения и записи клон снимка. После достижения нужного результата в клоне, клон повышается до набора данных, а старая файловая система удаляется. Удаление родительского набора данных не является обязательным, так как клон и набор данных могут без проблем сосуществовать.
# zfs clone camino/home/joe@backup camino/home/joenew
# ls /usr/home/joe*
/usr/home/joe:
backup.txz plans.txt
/usr/home/joenew:
backup.txz plans.txt
# df -h /usr/home
Filesystem Size Used Avail Capacity Mounted on
usr/home/joe 1.3G 31k 1.3G 0% /usr/home/joe
usr/home/joenew 1.3G 31k 1.3G 0% /usr/home/joenewСоздание клона делает его точной копией состояния набора данных на момент создания снимка. Теперь можно изменять клон независимо от исходного набора данных. Связь между ними осуществляется через снимок. ZFS записывает эту связь в свойстве origin. Повышение клона с помощью zfs promote делает клон независимым набором данных. Это удаляет значение свойства origin и отключает новый независимый набор данных от снимка. Вот пример:
# zfs get origin camino/home/joenew
NAME PROPERTY VALUE SOURCE
camino/home/joenew origin camino/home/joe@backup -
# zfs promote camino/home/joenew
# zfs get origin camino/home/joenew
NAME PROPERTY VALUE SOURCE
camino/home/joenew origin - -После внесения изменений, таких как копирование loader.conf в продвинутую клон-копию, например, старый каталог в этом случае становится устаревшим. Вместо него продвинутая клон-копия может его заменить. Для этого сначала выполните zfs destroy для старого набора данных, а затем zfs rename для клона, указав имя старого набора данных (или совершенно другое имя).
# cp /boot/defaults/loader.conf /usr/home/joenew
# zfs destroy -f camino/home/joe
# zfs rename camino/home/joenew camino/home/joe
# ls /usr/home/joe
backup.txz loader.conf plans.txt
# df -h /usr/home
Filesystem Size Used Avail Capacity Mounted on
usr/home/joe 1.3G 128k 1.3G 0% /usr/home/joeКлонированный снимок теперь является обычным набором данных. Он содержит все данные из исходного снимка, а также добавленные файлы, такие как loader.conf. Клоны предоставляют полезные возможности пользователям ZFS в различных сценариях. Например, можно предоставлять клетки в виде снимков с различными наборами установленных приложений. Пользователи могут клонировать эти снимки и добавлять свои собственные приложения по своему усмотрению. После внесения необходимых изменений клоны можно повысить до полноценных наборов данных и предоставить их конечным пользователям для работы, как с обычными наборами данных. Это экономит время и снижает административные затраты при предоставлении таких клеток.
23.4.9. Блочное клонирование
Блочное клонирование обеспечивает копирование при записи для отдельных копий файлов. При его включении копирование файла с помощью cp(1) не дублирует данные файла. Вместо этого новый файл ссылается на те же блоки, что и оригинал, и ZFS записывает новые блоки только тогда, когда впоследствии изменяется один из файлов. cp(1) выполняет копирование с помощью copy_file_range(2), которое ZFS превращает в операции блочного клонирования, делая копии внутри пула практически мгновенными и изначально не потребляющими дополнительное пространство.
В отличие от дедупликация, блочное клонирование не поддерживает требующую много памяти таблицу контрольных сумм. Совместное использование происходит только в момент копирования, и запись одинаковых данных отдельными операциями по-прежнему сохраняет их дважды. В отличие от клонов, блочное клонирование не требует снимка, работает с отдельными файлами, а не с целыми наборами данных, и не оставляет отношения origin после себя.
Блочное клонирование требует возможности пула block_cloning из OpenZFS 2.2, впервые выпущенной в FreeBSD 14.0 (см. zpool-features(7)). Управляющая системная переменная sysctl(8) vfs.zfs.bclone_enabled определяет, создаёт ли ZFS блочные клоны на самом деле. По умолчанию она равна 0 в FreeBSD 14.x и 1 в FreeBSD 15.0. Пока sysctl равен 0, copy_file_range() возвращается к обычному копированию. Чтобы включить блочное клонирование в FreeBSD 14.x:
# sysctl vfs.zfs.bclone_enabled=1
vfs.zfs.bclone_enabled: 0 -> 1Чтобы сохранить эту настройку после перезагрузок, добавьте следующую строку в /etc/sysctl.conf:
vfs.zfs.bclone_enabled=1
Свойства пула bcloneused, bclonesaved и bcloneratio показывают пространство, используемое клонированными блоками, пространство, сэкономленное за счёт клонирования, и результирующий коэффициент экономии:
# cp /var/tmp/database.dump /var/tmp/database.copy
# zpool list -o name,bcloneused,bclonesaved,bcloneratio mypool
NAME BCLONE_USED BCLONE_SAVED BCLONE_RATIO
mypool 1.7G 1.7G 2.00x23.4.10. Репликация
Хранение данных в единственном пуле в одном месте подвергает их рискам, таким как кража, стихийные бедствия или действия людей. Регулярное резервное копирование всего пула крайне важно. ZFS предоставляет встроенную функцию сериализации, которая может отправлять потоковое представление данных на стандартный вывод. Используя эту функцию, можно сохранять эти данные в другом пуле, подключённом к локальной системе, или отправлять их по сети на другую систему. Снимки являются основой для этой репликации (см. раздел о снимках ZFS). Команды, используемые для репликации данных, — это zfs send и zfs receive.
Эти примеры демонстрируют репликацию ZFS с использованием следующих двух пулов:
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
backup 960M 77K 896M - - 0% 0% 1.00x ONLINE -
mypool 984M 43.7M 940M - - 0% 4% 1.00x ONLINE -Имя пула mypool — это основной пул, в который данные регулярно записываются и откуда они читаются. Используйте второй резервный пул backup на случай, если основной пул станет недоступен. Обратите внимание, что этот переход на резервный пул не выполняется автоматически в ZFS, а должен быть осуществлён вручную системным администратором при необходимости. Используйте снимок (snapshot), чтобы обеспечить согласованную версию файловой системы для репликации. После создания снимка mypool скопируйте его в пул backup путём репликации снимков. Это не включает изменения, сделанные после последнего снимка.
# zfs snapshot mypool@backup1
# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
mypool@backup1 0 - 43.6M -Теперь, когда снимок существует, используйте zfs send для создания потока, представляющего содержимое снимка. Сохраните этот поток в файл или примите его в другом пуле. Поток записывается в стандартный вывод, но перенаправьте его в файл или канал, иначе появится ошибка:
# zfs send mypool@backup1
Error: Stream can not be written to a terminal.
You must redirect standard output.Для резервного копирования набора данных с помощью zfs send перенаправьте вывод в файл, расположенный в подключённом пуле резервных копий. Убедитесь, что в пуле достаточно свободного места для размещения отправленного снимка, то есть для данных, содержащихся в снимке, а не для изменений по сравнению с предыдущим снимком.
# zfs send mypool@backup1 > /backup/backup1
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
backup 960M 63.7M 896M - - 0% 6% 1.00x ONLINE -
mypool 984M 43.7M 940M - - 0% 4% 1.00x ONLINE -Команда zfs send передала все данные из снимка backup1 в пул backup. Для автоматического создания и отправки таких снимков используйте задание cron(8).
Вместо хранения резервных копий в виде архивных файлов ZFS может получать их как активную файловую систему, обеспечивая прямой доступ к резервным данным. Для доступа к фактическим данным, содержащимся в этих потоках, используйте zfs receive, чтобы преобразовать потоки обратно в файлы и каталоги. В приведённом ниже примере объединяются zfs send и zfs receive с использованием конвейера для копирования данных из одного пула в другой. После завершения передачи данные можно использовать напрямую в целевом пуле. Реплицировать набор данных можно только в пустой набор данных.
# zfs snapshot mypool@replica1
# zfs send -v mypool@replica1 | zfs receive backup/mypool
full send of mypool@replica1 estimated size is 50.1M
total estimated size is 50.1M
TIME SENT SNAPSHOT mypool@replica1
10:22:01 9.75M mypool@replica1
10:22:02 25.4M mypool@replica1
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
backup 960M 63.7M 896M - - 0% 6% 1.00x ONLINE -
mypool 984M 43.7M 940M - - 0% 4% 1.00x ONLINE -23.4.10.1. Инкрементные резервные копии
zfs send также может определить разницу между двумя снимками и отправить отдельные различия между ними. Это экономит место на диске и время передачи. Например:
# zfs snapshot mypool@replica2
# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
mypool@replica1 5.72M - 43.6M -
mypool@replica2 0 - 44.1M -
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
backup 960M 61.7M 898M - - 0% 6% 1.00x ONLINE -
mypool 960M 50.2M 910M - - 0% 5% 1.00x ONLINE -Создайте второй снимок с именем replica2. Этот второй снимок содержит изменения, внесённые в файловую систему в период между текущим моментом и предыдущим снимком replica1. Использование zfs send -i с указанием пары снимков создаёт инкрементальный поток репликации, содержащий изменённые данные. Это выполняется успешно, если исходный снимок уже существует на принимающей стороне.
# zfs send -v -i mypool@replica1 mypool@replica2 | zfs receive backup/mypool
send from @replica1 to mypool@replica2 estimated size is 5.02M
total estimated size is 5.02M
TIME SENT SNAPSHOT mypool@replica2
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
backup 960M 80.8M 879M - - 0% 8% 1.00x ONLINE -
mypool 960M 50.2M 910M - - 0% 5% 1.00x ONLINE -
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
backup 55.4M 240G 152K /backup
backup/mypool 55.3M 240G 55.2M /backup/mypool
mypool 55.6M 11.6G 55.0M /mypool
# zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
backup/mypool@replica1 104K - 50.2M -
backup/mypool@replica2 0 - 55.2M -
mypool@replica1 29.9K - 50.0M -
mypool@replica2 0 - 55.0M -Инкрементный поток реплицировал изменённые данные вместо полной копии replica1. Передача только различий заняла гораздо меньше времени и сэкономила место на диске, избегая копирования всего пула каждый раз. Это особенно полезно при репликации по медленной сети или при тарификации за каждый переданный байт.
Доступна новая файловая система backup/mypool с файлами и данными из пула mypool. Указание -p копирует свойства наборов данных, включая настройки сжатия, квоты и точки монтирования. Указание -R копирует все дочерние наборы данных вместе с их свойствами. Автоматизируйте отправку и получение для создания регулярных резервных копий во втором пуле. Раздел «Параметры потока отправки» более подробно описывает эти и другие полезные параметры.
23.4.10.2. Параметры отправки потока
zfs send предоставляет параметры, которые управляют тем, что включает поток и насколько он компактен. Указание -p включает свойства набора данных, такие как настройки сжатия, квоты и точки монтирования, в поток. Указание -R генерирует пакет репликационного потока, который включает набор данных, все дочерние наборы данных, снимки, клоны и свойства вплоть до именованного снимка, и подразумевает -p. Пример в Отправка зашифрованных бекапов через SSH использует -R для репликации полного дерева набора данных. Указание -v выводит информацию о сгенерированном потоке, включая отчет о ходе выполнения за секунду.
Другие параметры изменяют формат блоков данных в потоке:
-Lразрешает блоки размером более 128 КБ в потоке, сохраняя размер блоков на диске для наборов данных сrecordsizeвыше 128 КБ вместо разделения таких блоков.-eсоздаёт более компактный поток, используя записиWRITE_EMBEDDEDдля крошечных блоков, которые функция пулаembedded_dataхранит непосредственно в указателе блока.-cотправляет блоки, сжатые на диске, в их сжатом виде, а не распаковывает их сначала, экономя время процессора на обеих системах и сокращая объем передаваемых данных для сжатых наборов данных.-wотправляет зашифрованный набор данных в необработанном виде, точно так, как он хранится на диске, и без загрузки его ключа шифрования, как описано в разделе Отправка зашифрованных наборов данных. Для незашифрованных наборов данных-wэквивалентно-Lec.
Объединение этих параметров как zfs send -Lec является хорошим выбором по умолчанию для современных пулов. Принимающий пул должен поддерживать все возможности, которые использует поток, и zfs receive отклоняет поток, требующий возможности, отсутствующей в пуле. Смотрите zfs-send(8) и zpool-features(7) для полного списка параметров и возможностей пула, от которых они зависят.
23.4.10.3. Возобновляемые передачи
Разорванное сетевое соединение или перезагрузка во время большой передачи обычно означает, что нужно начинать заново. Использование zfs receive -s сохраняет частично принятое состояние на принимающем наборе данных вместо его удаления, когда поток завершается преждевременно.
# zfs send -v mypool@replica1 | zfs receive -s backup/mypool
full send of mypool@replica1 estimated size is 50.1M
total estimated size is 50.1M
TIME SENT SNAPSHOT mypool@replica1
10:31:01 9.75M mypool@replica1
^CПосле прерывания принимающий набор данных сохраняет непрозрачный токен возобновления в своём свойстве receive_resume_token. Токен записывает, какой снимок содержал прерванный поток и какая его часть была получена. Передача токена команде zfs send -t создаёт новый поток, который продолжает с того места, где передача остановилась:
# zfs get -H -o value receive_resume_token backup/mypool
1-1211c4f4a-f8-789c636064000310a501c49c50360710a715e5e7a69766a63040c1eabb735735ce8f8d5420c0e5c9e8d4d3d28a5388e4d3d200
# zfs send -t $(zfs get -H -o value receive_resume_token backup/mypool) | zfs receive -s backup/mypoolВозобновлённая передача завершается нормально и удаляет сохранённое частичное состояние. Пока передача не возобновлена или не прервана, частичное состояние занимает место в принимающем пуле и блокирует другие приёмы в тот же набор данных. Чтобы отказаться от прерванной передачи вместо её возобновления, используйте zfs receive -A для удаления сохранённого частичного состояния:
# zfs receive -A backup/mypool23.4.10.4. Отправка зашифрованных резервных копий через SSH
Отправка потоков данных по сети — это хороший способ создания удалённой резервной копии, но у этого метода есть недостаток. Данные, передаваемые по сетевому соединению, не шифруются, что позволяет любому перехватить их и преобразовать обратно в данные без ведома отправителя. Это нежелательно при отправке потоков через интернет на удалённый хост. Используйте SSH для безопасного шифрования данных, передаваемых по сетевому соединению. Поскольку ZFS требует перенаправления потока из стандартного вывода, его легко передать через SSH с помощью конвейера. Чтобы содержимое файловой системы оставалось зашифрованным и на удалённой системе, используйте встроенное шифрование и отправляйте набор данных в виде необработанного (raw) потока, как описано в «Отправка зашифрованных наборов данных».
Измените некоторые настройки и сначала примите меры безопасности. Здесь описаны необходимые шаги для операции zfs send; дополнительную информацию о SSH см. в OpenSSH.
Измените конфигурацию следующим образом:
Беспарольный доступ SSH между отправляющим и принимающим хостами с использованием SSH-ключей
Для отправки и получения потоков ZFS требуются привилегии пользователя
root. Это подразумевает вход в принимающую систему под учётной записьюroot.По соображениям безопасности вход пользователя
rootпо умолчанию запрещён.Используйте систему Делегирование ZFS, чтобы разрешить пользователю без прав
rootна каждой системе выполнять соответствующие операции отправки и получения. На передающей системе:
# zfs allow -u someuser send,snapshot mypoolЧтобы подключить пул, непривилегированный пользователь должен быть владельцем каталога, а обычные пользователи должны иметь разрешение на подключение файловых систем.
На принимающей системе:
# sysctl vfs.usermount=1
vfs.usermount: 0 -> 1
# echo vfs.usermount=1 >> /etc/sysctl.conf
# zfs create recvpool/backup
# zfs allow -u someuser create,mount,receive recvpool/backup
# chown someuser /recvpool/backupНепривилегированный пользователь теперь может получать и монтировать наборы данных, а также реплицирует набор данных home на удалённую систему:
% zfs snapshot -r mypool/home@monday
% zfs send -R mypool/home@monday | ssh someuser@backuphost zfs recv -dvu recvpool/backupСоздайте рекурсивный снимок с именем monday для набора данных файловой системы home в пуле mypool. Затем zfs send -R включает в поток набор данных, все дочерние наборы данных, снимки, клоны и настройки. Передайте вывод через SSH на ожидающий zfs receive на удалённом хосте backuphost. Рекомендуется использовать IP-адрес или полное доменное имя. Принимающая машина записывает данные в набор данных backup в пуле recvpool. Добавление опции -d к команде zfs recv отбрасывает первый элемент пути отправленного снимка (обычно это имя пула) и присоединяет оставшуюся часть пути к принимаемому набору данных, создавая при необходимости все промежуточные файловые системы. -u отключает монтирование файловых систем на принимающей стороне. Использование -v показывает подробности о передаче, включая затраченное время и объём переданных данных.
23.4.10.5. Корректирующий приём
Процедура проверки (scrub) обнаруживает поврежденные данные, но в пуле без достаточной избыточности она не может исправить повреждения и вместо этого сообщает о постоянных ошибках. Если на другом пуле существует неповрежденная копия затронутого снимка, корректирующий прием с помощью zfs receive -c восстанавливает поврежденные блоки на месте, используя поток отправки как источник здоровых данных. Набор данных остается на своем месте, без каких-либо откатов или переименований.
Корректирующий приём требует OpenZFS 2.2, впервые поставленный во FreeBSD 14.0. |
В этом примере проверка пула mypool на одном диске обнаружила неустранимые повреждения:
# zpool status -v mypool
pool: mypool
state: ONLINE
status: One or more devices has experienced an error resulting in data
corruption. Applications may be affected.
action: Restore the file in question if possible. Otherwise restore the
entire pool from backup.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A
scan: scrub repaired 0B in 00:01:22 with 1 errors on Sat Jul 11 09:14:37 2026
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
ada0 ONLINE 0 0 2
errors: Permanent errors have been detected in the following files:
/mypool/reports/summary-2026.dbСнимок replica2 по-прежнему ссылается на повреждённые блоки, а пул backup содержит неповреждённую копию этого снимка. Отправьте снимок из пула backup и получите его корректирующе в соответствующий снимок на повреждённом пуле, затем выполните проверку (scrub), чтобы подтвердить восстановление:
# zfs send backup/mypool@replica2 | zfs receive -c mypool@replica2
# zpool scrub -w mypool
# zpool status mypool | grep errors:
errors: No known data errorsПоток должен содержать тот же снапшот, который существует на повреждённом наборе данных. Корректирующий приём восстанавливает только те блоки данных, которые присутствуют в потоке; он не может исправить метаданные или данные, записанные после создания снапшота. После этого всегда выполняйте scrub, чтобы убедиться, что пул больше не содержит повреждённых данных.
23.4.11. Квоты наборов данных, пользователей и групп
Используйте Квоты наборов данных, чтобы ограничить объём пространства, используемого определённым набором данных. Референтные квоты работают схожим образом, но учитывают пространство, используемое самим набором данных, исключая снимки и дочерние наборы данных. Аналогично, используйте пользовательские и групповые квоты, чтобы предотвратить исчерпание всего пространства в пуле или наборе данных пользователями или группами. Квоты проектов, описанные ниже, ограничивают занимаемое пространство для произвольного дерева каталогов.
Следующие примеры предполагают, что пользователи уже существуют в системе. Перед добавлением пользователя в систему убедитесь, что вы сначала создали его домашний набор данных и установили mountpoint в /home/bob. Затем создайте пользователя и укажите домашний каталог на расположение mountpoint набора данных. Это правильно установит права владельца и группы без перекрытия уже существующих путей домашних каталогов.
Чтобы установить квоту набора данных в 10 ГБ для storage/home/bob:
# zfs set quota=10G storage/home/bobЧтобы установить контрольную квоту в 10 ГБ для storage/home/bob:
# zfs set refquota=10G storage/home/bobУдалить квоту в 10 ГБ для storage/home/bob:
# zfs set quota=none storage/home/bobОбщий формат userquota@пользователь=размер, и имя пользователя должно быть в одном из следующих форматов:
POSIX-совместимое имя, например joe.
Числовой идентификатор POSIX, например, 789.
Имя SID, например, joe.bloggs@example.com.
Числовой идентификатор SID, например, S-1-123-456-789.
Например, чтобы установить пользовательскую квоту в 50 ГБ для пользователя с именем joe:
# zfs set userquota@joe=50G storage/home/joeЧтобы удалить любую квоту:
# zfs set userquota@joe=none storage/home/joeСвойства квот пользователей не отображаются командой |
Общий формат для установки квоты группы: groupquota@группа=размер.
Чтобы установить квоту для группы firstgroup в 50 ГБ, используйте:
# zfs set groupquota@firstgroup=50G storage/homeЧтобы удалить квоту для группы firstgroup или убедиться, что она не установлена, используйте вместо этого:
# zfs set groupquota@firstgroup=none storage/homeКак и в случае с пользовательскими квотами, пользователи без прав root могут видеть квоты, связанные с группами, к которым они принадлежат. Пользователь с привилегией groupquota или root может просматривать и устанавливать квоты для всех групп.
Для отображения объёма пространства, используемого каждым пользователем в файловой системе или снимке, вместе с квотами, используйте zfs userspace. Для информации о группах используйте zfs groupspace. Подробнее о поддерживаемых опциях или о том, как отобразить только определённые опции, см. в zfs-userspace(8).
Привилегированные пользователи и root могут просмотреть квоту для storage/home/bob, используя:
# zfs get quota storage/home/bob23.4.11.1. Проектные квоты
Квоты наборов данных и пользователей подходят не для любой структуры. Когда несколько деревьев каталогов, принадлежащих разным проектам, используют один набор данных, квоты проектов ограничивают пространство, потребляемое каждым деревом, вместо этого. Проект — это произвольный числовой идентификатор, присваиваемый файлам и каталогам.
zfs project управляет идентификатором проекта файлов и каталогов. Установка флага наследования проекта на каталог приводит к тому, что новые файлы и подкаталоги, созданные внутри него, наследуют его идентификатор проекта. Чтобы назначить идентификатор проекта 42 существующему дереву, рекурсивно установите флаг и идентификатор:
# zfs project -s -p 42 -r /storage/projНаложить ограничение в 100 ГБ на все файлы, принадлежащие проекту 42, с помощью свойства projectquota:
# zfs set projectquota@42=100G storagezfs projectspace отображает пространство, потребляемое каждым проектом на наборе данных, а также любые квоты:
# zfs projectspace -o name,used,quota storage
NAME USED QUOTA
42 1.95G 100GСвойство projectobjquota ограничивает количество объектов, которыми может владеть проект, аналогичным образом. Отобразите или очистите идентификатор проекта для каталога с помощью zfs project -d и zfs project -C. Подробности см. в zfs-project(8) и zfsprops(7).
23.4.12. Резервирования
Резервирования гарантируют всегда доступный объём пространства в наборе данных. Зарезервированное пространство не будет доступно для других наборов данных. Эта полезная функция обеспечивает наличие свободного места для важных наборов данных или файлов журналов.
Общий формат свойства reservation — reservation=размер, поэтому, чтобы установить резервирование в 10 ГБ для storage/home/bob, используйте:
# zfs set reservation=10G storage/home/bobЧтобы очистить любое резервирование:
# zfs set reservation=none storage/home/bobТот же принцип применяется к свойству refreservation для установки Референсного резервирования, с общим форматом refreservation=размер.
Эта команда показывает все и резервирования (reservation), и референсные резервирования (refreservation), существующие в storage/home/bob:
# zfs get reservation storage/home/bob
# zfs get refreservation storage/home/bob23.4.13. Сжатие
ZFS предоставляет прозрачное сжатие. Сжатие данных на уровне блоков экономит место и увеличивает пропускную способность диска. Если данные сжимаются на 25%, то сжатые данные записываются на диск с той же скоростью, что и несжатые, что приводит к эффективной скорости записи в 125%. Сжатие также может быть отличной альтернативой Дедупликации, так как не требует дополнительной памяти.
ZFS предлагает различные алгоритмы сжатия, каждый со своими компромиссами. В OpenZFS 2.2 и новее для вновь создаваемых пулов и наборов данных по умолчанию установлено значение compression=on, которое выбирает алгоритм LZ4. Сжатие LZ4 позволяет сжимать весь пул без значительного снижения производительности, характерного для других алгоритмов. Главное преимущество LZ4 — функция раннего прерывания. Если LZ4 не достигает как минимум 12,5% сжатия в заголовочной части данных, ZFS записывает блок без сжатия, чтобы избежать потерь процессорного времени на попытки сжать уже сжатые или несжимаемые данные. Изменение свойства compression влияет только на новые записи; существующие данные сохраняют свою старую кодировку до тех пор, пока не будут перезаписаны (см. «Перезапись существующих данных»). Подробнее о различных алгоритмах сжатия, доступных в ZFS, см. в разделе Сжатие терминологии.
Администратор может оценить эффективность сжатия, используя свойства набора данных.
# zfs get used,compressratio,compression,logicalused mypool/compressed_dataset
NAME PROPERTY VALUE SOURCE
mypool/compressed_dataset used 449G -
mypool/compressed_dataset compressratio 1.11x -
mypool/compressed_dataset compression lz4 local
mypool/compressed_dataset logicalused 496G -Набор данных использует 449 ГБ пространства (свойство used). Без сжатия он занял бы 496 ГБ пространства (свойство logicalused). Это даёт коэффициент сжатия 1.11:1.
Сжатие может иметь неожиданный побочный эффект при использовании вместе с Квотами пользователей. Квоты пользователей ограничивают фактическое пространство, которое пользователь занимает на наборе данных после сжатия. Если у пользователя есть квота в 10 ГБ, и он записывает 10 ГБ сжимаемых данных, он всё равно сможет сохранить больше данных. Если позже пользователь обновит файл, например базу данных, более или менее сжимаемыми данными, количество доступного ему пространства изменится. Это может привести к необычной ситуации, когда пользователь не увеличил фактический объём данных (свойство logicalused), но изменение степени сжатия привело к достижению предела его квоты.
Сжатие может иметь схожий непредвиденный эффект при взаимодействии с резервными копиями. Квоты часто используются для ограничения хранимых данных, чтобы гарантировать наличие достаточного места для резервного копирования. Поскольку квоты не учитывают сжатие, ZFS может записать больше данных, чем поместилось бы при резервном копировании без сжатия.
23.4.14. Сжатие алгоритмом Zstandard
В OpenZFS 2.0 был добавлен алгоритм сжатия Zstandard (Zstd). Zstd обеспечивает более высокие коэффициенты сжатия по сравнению с используемым по умолчанию LZ4, при этом работая значительно быстрее альтернативного gzip.
Zstd предоставляет широкий выбор уровней сжатия, обеспечивая детальный контроль над производительностью и степенью сжатия. Одним из основных преимуществ Zstd является то, что скорость распаковки не зависит от уровня сжатия. Для данных, которые записываются один раз, но часто читаются, Zstd позволяет использовать максимальные уровни сжатия без потери производительности при чтении.
Даже при частом обновлении данных включение сжатия часто обеспечивает более высокую производительность. Одно из главных преимуществ связано с функцией сжатого ARC. Адаптивный кэш замещения (ARC Adaptive Replacement Cache) в ZFS хранит сжатую версию данных в оперативной памяти, распаковывая их при каждом обращении. Это позволяет хранить больше данных и метаданных в том же объёме памяти, повышая коэффициент попадания в кэш.
ZFS предлагает 19 уровней сжатия Zstd, каждый из которых обеспечивает постепенное увеличение экономии места в обмен на более медленное сжатие. Уровень по умолчанию — zstd-3, который обеспечивает лучшее сжатие, чем LZ4, без значительного снижения скорости. Уровни выше 10 требуют большого объёма памяти для сжатия каждого блока, и системы с менее чем 16 ГБ ОЗУ не должны их использовать. ZFS также использует подмножество уровней Zstd fast, которые работают быстрее, но обеспечивают меньшую степень сжатия. ZFS поддерживает уровни от zstd-fast-1 до zstd-fast-10, от zstd-fast-20 до zstd-fast-100 с шагом 10, а также zstd-fast-500 и zstd-fast-1000, которые обеспечивают минимальное сжатие, но обладают высокой производительностью.
Если ZFS не может получить необходимую память для сжатия блока с помощью Zstd, он переходит к сохранению блока в несжатом виде. Это маловероятно, за исключением случаев использования максимальных уровней Zstd на системах с ограниченной памятью. ZFS подсчитывает, сколько раз это произошло с момента загрузки модуля ZFS, с помощью kstat.zfs.misc.zstd.compress_alloc_fail.
23.4.15. Перезапись существующих данных
|
Свойства, такие как compression, checksum, dedup и copies, влияют только на вновь записываемые данные. Их изменение оставляет существующие блоки сохранёнными как есть, и применение новых значений традиционно требовало цикла отправки/получения или копирования каждого файла туда и обратно. zfs rewrite вместо этого перезаписывает блоки существующих файлов на месте, как если бы они были атомарно прочитаны и записаны обратно, поэтому текущие значения свойств вступают в силу без этих обходных путей.
Команда работает с файлами и каталогами, а не с именами наборов данных. Чтобы применить вновь выбранный алгоритм сжатия ко всему набору данных, выполните рекурсивный обход от его точки монтирования:
# zfs set compression=zstd mypool/archive
# zfs rewrite -r /mypool/archiveДобавление -v выводит имя каждого перезаписанного файла. -x предотвращает переход рекурсии через точки монтирования в дочерние наборы данных, а -o и -l ограничивают перезапись диапазоном байт внутри файла. Изменения свойств, которые могли бы изменить логический размер блока, такие как recordsize, не влияют на перезаписанные файлы.
Переписанные блоки — это новые блоки: снимки, сделанные до перезаписи, продолжают ссылаться на старые копии, поэтому использование дискового пространства может расти, пока эти снимки не будут уничтожены. zfs rewrite не работает через снимки по той же причине. Подробности см. в zfs-rewrite(8).
23.4.16. Дедупликация
Когда включена перекрёстная дедупликация, она использует контрольную сумму каждого блока для обнаружения дублирующихся блоков. Когда новый блок является дубликатом существующего блока, ZFS записывает новую ссылку на существующие данные вместо всего дублирующегося блока. Возможна значительная экономия места, если данные содержат много дублирующихся файлов или повторяющейся информации. Предупреждение: дедупликация требует большого объёма памяти, а включение сжатия обеспечивает большую часть экономии места без дополнительных затрат.
dedup является свойством набора данных, а не свойством пула. Чтобы активировать дедупликацию, установите это свойство на наборе данных:
# zfs set dedup=on poolЭтот пример устанавливает свойство на корневом наборе данных пула pool, поэтому каждый набор данных в пуле наследует его. Ограничение дедупликации только наборами данных, которые действительно хранят данные с большим количеством дубликатов, позволяет поддерживать таблицу дедупликации меньшего размера.
Дедупликация затрагивает только новые данные, записываемые в набор данных. Простое включение этой опции не приведёт к дедупликации уже записанных данных. В FreeBSD 15.0 zfs rewrite позволяет перезаписать существующие данные так, чтобы они прошли через дедупликацию. Пул с только что активированным свойством дедупликации будет выглядеть следующим образом:
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
pool 2.84G 2.19M 2.83G - - 0% 0% 1.00x ONLINE -Столбец DEDUP показывает фактический уровень дедупликации для пула. Значение 1.00x означает, что данные пока не дедуплицированы. В следующем примере некоторые системные двоичные файлы копируются три раза в разные каталоги в пуле с дедупликацией, созданном выше.
# for d in dir1 dir2 dir3; do
> mkdir $d && cp -R /usr/bin $d &
> doneДля наблюдения за дедупликацией избыточных данных используйте:
# zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
pool 2.84G 20.9M 2.82G - - 0% 0% 3.00x ONLINE -Столбец DEDUP показывает коэффициент 3.00x. Обнаружение и дедупликация копий данных используют треть пространства. Потенциальная экономия пространства может быть огромной, но достигается за счет наличия достаточного объёма памяти для отслеживания дедуплицированных блоков. ZFS хранит запись для каждого дедуплицированного блока в таблице дедупликации (DDT). Эмпирическое правило гласит, что требуется 5–6 ГБ оперативной памяти на 1 ТБ дедуплицированных данных. Когда таблица перестаёт помещаться в памяти, каждая запись вынуждает считывать элементы таблицы с диска, и производительность резко падает.
Дедупликация не всегда полезна, если данные в пуле не содержат избыточности. ZFS может показать потенциальную экономию пространства, имитируя дедупликацию на существующем пуле:
# zdb -S pool
Simulated DDT histogram:
bucket allocated referenced
______ ______________________________ ______________________________
refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE
------ ------ ----- ----- ----- ------ ----- ----- -----
1 2.58M 289G 264G 264G 2.58M 289G 264G 264G
2 206K 12.6G 10.4G 10.4G 430K 26.4G 21.6G 21.6G
4 37.6K 692M 276M 276M 170K 3.04G 1.26G 1.26G
8 2.18K 45.2M 19.4M 19.4M 20.0K 425M 176M 176M
16 174 2.83M 1.20M 1.20M 3.33K 48.4M 20.4M 20.4M
32 40 2.17M 222K 222K 1.70K 97.2M 9.91M 9.91M
64 9 56K 10.5K 10.5K 865 4.96M 948K 948K
128 2 9.50K 2K 2K 419 2.11M 438K 438K
256 5 61.5K 12K 12K 1.90K 23.0M 4.47M 4.47M
1K 2 1K 1K 1K 2.98K 1.49M 1.49M 1.49M
Total 2.82M 303G 275G 275G 3.20M 319G 287G 287G
dedup = 1.05, compress = 1.11, copies = 1.00, dedup * compress / copies = 1.16После завершения анализа пула командой zdb -S отображается коэффициент сокращения пространства, который был бы достигнут при активации дедупликации. В данном случае значение 1.16 указывает на низкий уровень экономии пространства, в основном обеспечиваемый сжатием. Активация дедупликации для этого пула не сэкономит значительного объёма пространства и не оправдает объём памяти, необходимый для её включения. Используя формулу ratio = dedup * compress / copies, системные администраторы могут планировать распределение хранилища, определяя, будет ли рабочая нагрузка содержать достаточное количество дублирующихся блоков, чтобы оправдать требования к памяти. Если данные достаточно хорошо сжимаемы, экономия пространства может быть значительной.
Быстрое дедуплицирование, переработанная реализация, снижающая эти затраты, требует OpenZFS 2.3 или более поздней версии, впервые доступной в FreeBSD 15.0. Быстрое дедуплицирование группирует обновления таблицы дедупликации в журнале на диске и сбрасывает их в таблицу в фоновом режиме, снижая случайный ввод-вывод, из-за которого классическая дедупликация была медленной. Свойство пула dedup_table_quota задаёт ограничение на размер таблицы на диске; ZFS прекращает добавлять новые записи, когда пул достигает лимита, а при значении по умолчанию auto размер выделенного vdev для дедупликации служит квотой. Свойство пула dedup_table_size, доступное только для чтения, сообщает текущий размер таблицы. zpool ddtprune -p 30 pool удаляет самые старые 30% записей таблицы, которые не дают экономии, поскольку на них ссылается только один блок; -d days вместо этого удаляет записи с одной ссылкой, старше указанного количества дней. zpool status -DD pool отображает статистику таблицы дедупликации, включая гистограмму блоков по количеству ссылок. Хранение таблицы на выделенном для дедупликации vdev, состоящем из быстрых устройств, обеспечивает быстрый поиск даже когда таблица превышает объём оперативной памяти.
Хорошей практикой является сначала включить сжатие, так как сжатие также обеспечивает значительно повышенную производительность. Включайте дедупликацию в случаях, когда экономия значительна и имеется достаточно доступной памяти для DDT.
23.4.17. ZFS и клетки
Используйте zfs jail и соответствующее свойство jailed, чтобы делегировать набор данных ZFS в Клетку. zfs jail идентификатор_клетки присоединяет набор данных к указанной клетке, а zfs unjail отсоединяет его. Для управления набором данных изнутри клетки установите свойство jail. ZFS запрещает монтирование на хосте набора данных со свойством jail, так как его точки монтирования могут нарушить безопасность хоста.
Делегированный набор данных передает управление всем поддеревом администратору клетки, который может монтировать его, создавать дочерние наборы данных, делать снимки и изменять свойства, все это ограничено этим поддеревом. Для этого клетке необходимо включить параметры allow.mount и allow.mount.zfs, а параметр enforce_statfs установить на значение ниже 2. Обратитесь к jail(8) за подробностями об этих параметрах.
Этот пример создаёт набор данных, помечает его как находящийся в клетке и прикрепляет его к запущенной клетке myjail:
# zfs create mypool/jaildata
# zfs set jailed=on mypool/jaildata
# zfs jail myjail mypool/jaildataЗатем набор данных появляется в zfs list внутри клетки и доступен для управления там. zfs unjail myjail mypool/jaildata возвращает управление хосту. Дополнительную информацию см. в zfs-jail(8).
Начиная с FreeBSD 15.0, jail(8) автоматизирует подключение. Укажите наборы данных для делегирования в параметре клетки zfs.dataset, и jail(8) подключает их при запуске клетки. Наборы данных уже должны иметь установленный параметр jailed=on, а параметр требует allow.mount.zfs. Запись в /etc/jail.conf с его использованием выглядит так:
myjail {
path = "/usr/local/jails/myjail";
host.hostname = "myjail.example.org";
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
allow.mount;
allow.mount.zfs;
enforce_statfs = 1;
zfs.dataset = "mypool/jaildata";
}Установка параметра клетки zfs.mount_snapshot в значение 1 дополнительно позволяет пользователям внутри клетки получать доступ к содержимому снимков ZFS в каталоге .zfs делегированных файловых систем.
23.5. Делегированное администрирование
Комплексная система делегирования прав позволяет непривилегированным пользователям выполнять функции администрирования ZFS. Например, если домашний каталог каждого пользователя является набором данных, пользователям нужно разрешение на создание и удаление снимков своих домашних каталогов. Пользователь, выполняющий резервное копирование, может получить разрешение на использование функций репликации. ZFS позволяет скрипту статистики использования работать с доступом только к данным о занятом пространстве для всех пользователей. Также возможно делегирование права на делегирование разрешений. Делегирование прав доступно для каждой подкоманды и большинства свойств.
23.5.1. Делегирование создания наборов данных
zfs allow someuser create mydataset предоставляет указанному пользователю разрешение на создание дочерних наборов данных в выбранном родительском наборе данных. Важное замечание: создание нового набора данных включает его монтирование. Для этого необходимо установить параметр vfs.usermount в sysctl(8) FreeBSD в значение 1, чтобы разрешить непривилегированным пользователям монтировать файловую систему. Ещё одно ограничение, направленное на предотвращение злоупотреблений: непривилегированные пользователи должны быть владельцами точки монтирования, куда монтируется файловая система.
23.5.2. Делегирование права делегировать разрешения
zfs allow someuser allow mydataset предоставляет указанному пользователю возможность назначать любые разрешения, которые у него есть для целевого набора данных или его дочерних элементов, другим пользователям. Если пользователь имеет разрешение snapshot и разрешение allow, он может предоставить разрешение snapshot другим пользователям.
23.6. Встроенное шифрование ZFS
ZFS поддерживает встроенное шифрование наборов данных и данных, хранящихся в них. Так было не всегда: предыдущие решения полагались на шифрование на основе GELI во FreeBSD. Хотя этот подход безопасен, он не был так легко переносим на системы, отличные от FreeBSD, в которых отсутствовала поддержка GELI. Благодаря встроенному шифрованию ZFS зашифрованные наборы данных можно использовать на других системах, поддерживающих эту функцию пула, без зависимости от сторонних компонентов или встроенного шифрования операционной системы.
Ещё одним преимуществом встроенного шифрования ZFS является то, что наборы данных не нужно расшифровывать для административных задач, таких как создание снимков, репликация или операции проверки целостности. Проверки целостности данных ZFS работают одинаково хорошо с нативно зашифрованными наборами данных, а сжатие также работает с зашифрованными наборами данных.
Разные наборы данных в одном пуле могут использовать отдельные ключи независимо. Рассмотрим центральный файловый сервер, где разные пользователи хранят свои данные в зашифрованных домашних наборах данных. У пользователя A ключ отличается от ключа пользователя B. Оба пользователя могут работать параллельно и расшифровывать свои наборы данных по мере необходимости, не зная ключей расшифровки друг друга. Метод расшифровки также может полностью различаться между пользователями, не влияя друг на друга. Это позволяет хранить конфиденциальные данные разных пользователей в одном пуле, оставаясь защищёнными отдельными ключами.
Перед использованием встроенного шифрования ZFS, учтите следующее:
Шифрование применяется на уровне набора данных, а не на уровне пула.
Загрузка с зашифрованных наборов данных ZFS пока не поддерживается в загрузчике FreeBSD.
Шифрование может быть включено только при создании набора данных, а не после.
Блочный шифр, длина ключа и режим шифрования не могут быть изменены после того, как они были установлены.
ZFS не шифрует метаданные.
Последний пункт может показаться недостатком по сравнению с полнодисковым шифрованием. Однако он обеспечивает большую гибкость, позволяя разным ключам защищать наборы данных (datasets) в рамках одного пула, вместо того чтобы требовать один ключ или парольную фразу для разблокировки всего пула. В частности, ZFS шифрует следующее:
данные файла и zvol,
атрибуты файлов,
ACL,
биты разрешений,
листинги каталогов,
Соответствия FUID,
используемые пользователем/групповые используемые данные, и
Дедуплицированные данные
Некоторые метаданные и информация ZFS остаются незашифрованными, включая следующее:
структура и имя пула,
имена наборов данных и снимков,
иерархия наборов данных,
свойства,
размер файла
пропуски в файлах, и
Таблицы дедупликации
Этот набор незашифрованных метаданных позволяет ZFS выполнять рутинные операции обслуживания, такие как zpool scrub, без предварительной расшифровки данных. В результате ZFS может обнаруживать и исправлять повреждённые зашифрованные данные, не обращаясь к незашифрованному содержимому файлов.
Чтобы зашифровать существующие незашифрованные данные, скопируйте их в набор данных с включенным шифрованием. Это позволяет перенести данные в защищенное место в пуле, при условии предоставления парольной фразы для авторизации доступа. Обычно это делается путем загрузки ключа шифрования в память после подтверждения знания секрета, такого как парольная фраза. После загрузки ключа содержимое набора данных становится доступным для чтения и записи. Чтобы снова защитить набор данных, выгрузите ключ из памяти. Тогда ZFS сделает набор данных недоступным до тех пор, пока ключ не будет загружен снова.
Когда шифрование включено, некоторые операции ZFS ведут себя иначе. ZFS применяет сжатие перед шифрованием, чтобы сохранить коэффициенты сжатия. Хотя ZFS обычно использует 256-битные контрольные суммы, шифрование заменяет их на 128-битную контрольную сумму и 128-битный код аутентификации сообщения (MAC), предоставляемый набором шифрования. Это обеспечивает дополнительную защиту от злонамеренного изменения данных.
Когда дедупликация используется вместе с шифрованием, ZFS выполняет дедупликацию только в пределах зашифрованного набора данных, его снимков и его клонов. Это предотвращает утечку информации между зашифрованными наборами данных. Обратной стороной является более низкая эффективность дедупликации, поскольку ZFS не может сравнивать контрольные суммы по всему пулу. Тем не менее, дедупликация в сочетании с шифрованием всё равно раскрывает, какие блоки идентичны, и добавляет дополнительные накладные расходы на ЦП для каждого записываемого блока.
У шифрования ZFS также есть и другие ограничения. Возможность embedded_data не может использоваться с шифрованием. Наборы данных с включенным шифрованием также не могут иметь свойство copies, установленное в 3, поскольку реализация хранит зашифрованные метаданные в том месте, где обычно размещалась бы третья копия.
23.6.1. Создание зашифрованного набора данных
Шифрование ZFS включается путем установки свойства encryption=on при создании набора данных. Установка этого свойства вне команды zfs create не включает шифрование задним числом, поскольку оно действует только во время создания набора данных. В следующем примере для монтирования зашифрованного набора данных после его создания используется парольная фраза.
# zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt zroot/secretdata
Enter passphrase:
Re-enter passphrase:Если парольная фраза короче восьми символов, ZFS отклоняет её и не создаёт набор данных. После того как парольная фраза была введена правильно дважды, ZFS создаёт и монтирует набор данных в пуле.
Любые данные, хранящиеся в зашифрованном наборе данных, остаются зашифрованными, пока они там находятся. Копирование данных из зашифрованного набора данных в незашифрованное место расшифровывает данные во время операции копирования. Затем вновь созданный набор данных можно при необходимости смонтировать в другом месте.
# zfs set mountpoint=/secretdata zroot/secretdata
# echo "Hello FreeBSD!" > /secretdata/message
# cat /secretdata/message
Hello FreeBSD!Как и ожидалось, данные в настоящее время доступны для чтения и записи любому, у кого есть доступ к набору данных.
23.6.2. Свойства зашифрованных наборов данных
Перечисление свойств собственного шифрования ZFS для набора данных выполняется с помощью следующей команды:
# zfs get encryption,keylocation,keyformat zroot/secretdata
NAME PROPERTY VALUE SOURCE
zroot/secretdata encryption aes-256-gcm -
zroot/secretdata keylocation prompt local
zroot/secretdata keyformat passphrase -Свойство encryption показывает aes-256-gcm, который в настоящее время является методом шифрования, используемым ZFS по умолчанию. Как указано в столбце SOURCE, ни это свойство, ни свойство keyformat нельзя изменить с помощью zfs set после создания набора данных. Смотрите раздел изменение ключа шифрования для получения информации о том, как изменить некоторые из этих свойств. В следующей таблице перечислены свойства, связанные с шифрованием, используемые ZFS:
Набор данных, из которого текущий набор данных наследует свой ключ шифрования. Клоны наборов данных разделяют ключ шифрования своего исходного набора данных. | |
Формат ключа шифрования. Возможные значения: | |
Шифр, используемый для шифрования, состоящий из блочного шифра, длины ключа и режима шифрования. Свойства
Это свойство нельзя изменить после того, как оно было установлено. | |
Указывает, был ли успешно загружен ключ шифрования. Возможные значения: | |
Указывает местоположение, из которого следует загрузить ключ шифрования. Возможные значения: | |
Количество итераций, используемых при получении ключа шифрования из парольной фразы. Это вынуждает злоумышленника выполнять большое количество вычислительно затратных операций хеширования. По мере роста вычислительной мощности это значение также следует увеличивать с текущего значения по умолчанию, равного 350000. |
23.6.3. Выгрузка ключа шифрования
Защита данных, хранящихся в зашифрованном наборе данных, требует двух шагов: сначала размонтировать набор данных, затем выгрузить ключ шифрования из памяти. Это различие важно. Размонтированный набор данных не защищён, если его ключ шифрования остаётся загруженным в памяти. Всегда выполняйте zfs unload-key, чтобы защитить данные. Чтобы снова получить доступ к набору данных, загрузите ключ и укажите парольную фразу, как описано в разделе загрузка ключа шифрования. ZFS предотвращает выполнение zfs unload-key, пока набор данных всё ещё смонтирован.
# zfs unmount zroot/secretdata
# zfs unload-key zroot/secretdataВыполнение zfs unload-key несколько раз приводит к ошибке, указывающей на то, что ключ уже был выгружен.
23.6.4. Загрузка ключа шифрования
Прежде чем зашифрованный набор данных можно будет использовать, как и любой другой набор данных, необходимо загрузить его ключ шифрования и указать парольную фразу. На этом этапе свойство keystatus по-прежнему имеет значение unavailable, и монтирование набора данных завершается ошибкой, поскольку ключ ещё не был загружен:
# zfs get keystatus zroot/secretdata
NAME PROPERTY VALUE SOURCE
zroot/secretdata keystatus unavailable -
# zfs mount zroot/secretdata
cannot mount 'zroot/secretdata': encryption key not loadedЭто указывает на то, что набор данных зашифрован и требует ключ шифрования. Чтобы смонтировать набор данных, выполните zfs load-key и введите парольную фразу при появлении запроса:
# zfs load-key zroot/secretdata
Enter passphrase for 'zroot/secretdata':
# zfs get keystatus zroot/secretdata
NAME PROPERTY VALUE SOURCE
zroot/secretdata keystatus available -Затем смонтируйте набор данных, чтобы сделать его доступным через иерархию файловой системы:
# zfs mount zroot/secretdata
# mount|grep secretdata
zroot/secretdata on /secretdata (zfs, local, noatime, nfsv4acls)Чтобы рекурсивно загрузить несколько ключей шифрования, укажите параметр -r с командой zfs load-key. Если ключ уже был загружен, ZFS сообщает об этом сообщением об ошибке.
# zfs load-key zroot/secretdata
Key load error: Key already loaded for 'zroot/secretdata'.Свойство keystatus также подтверждает, что ключ был загружен, сообщая значение available. Чтобы проверить, корректен ли пароль, не загружая ключ, используйте параметр -n для выполнения пробного запуска.
23.6.5. Изменение ключа шифрования
ZFS также поддерживает смену ключей шифрования, например, замену парольной фразы. Эта операция не требует повторного шифрования набора данных. Выполните следующую команду, чтобы изменить парольную фразу шифрования:
# zfs change-key zroot/secretdata
Enter new passphrase for 'zroot/secretdata':
Re-enter new passphrase for 'zroot/secretdata':Выполнение zfs change-key требует, чтобы текущий ключ был загружен. Если он не загружен, ZFS всё равно запросит новый ключ, но затем выведет предупреждение о том, что текущий ключ не был загружен.
Команда zfs change-key также может изменять свойства keylocation, keyformat и pbkdf2iters, указывая их с помощью опции -o. Выполнение zfs change-key над зашифрованным дочерним набором данных делает его корнем шифрования, если он еще не является таковым. Чтобы предотвратить такое поведение и продолжить наследование ключа родительского набора, укажите опцию -i.
Имейте в виду, что смена ключа шифрования родительского набора данных также меняет ключ для дочерних наборов данных, которые его наследуют. Следовательно, эти дочерние наборы данных продолжают использовать ключ шифрования родителя. Если дочерний набор данных должен использовать другой ключ, либо укажите другой keyformat при его создании, либо выполните zfs change-key для дочернего набора данных. Это создаст новый корень шифрования для дочернего элемента и разорвёт его наследование шифрования от родителя.
Клоны ZFS зашифрованного набора данных всегда используют ключ шифрования своего исходного набора данных. В результате свойства keystatus, keyformat, keylocation и pbkdf2iters не наследуются, как другие свойства набора данных. Вместо этого они используют значения, определённые корнем шифрования. Чтобы определить корень шифрования, используйте свойство encryptionroot только для чтения.
Если злоумышленник скомпрометировал ключ шифрования, смена парольной фразы с помощью zfs change-key не обязательно защитит существующие или вновь записанные данные. Новые данные продолжают шифроваться тем же мастер-ключом, что и существующие. Если злоумышленник получит как пользовательский ключ, так и соответствующий обёрнутый мастер-ключ, выполнение zfs change-key не перезапишет предыдущий мастер-ключ на диске. В результате старый мастер-ключ может оставаться доступным для анализа данных в течение неопределённого периода времени.
Если мастер-ключ был скомпрометирован, предпочтительным решением является безопасное стирание нижележащих устройств хранения и создание нового пула. После этого восстановите данные из резервной копии в новый пул. Или создайте новый зашифрованный набор данных, перенесите данные с помощью zfs send и zfs receive, а затем выполните zpool trim --secure, чтобы стереть освободившееся пространство. Если нижележащее оборудование не поддерживает безопасный TRIM, вместо этого используйте zpool initialize.
23.6.6. Отправка зашифрованных наборов данных
Репликация ZFS основана на отправке снимков наборов данных, которые также могут быть созданы из зашифрованных наборов данных. Полученные снимки остаются зашифрованными.
# zfs snapshot zroot/secretdata@snap1В дополнение к отправке зашифрованных резервных копий через SSH, использование опции -w (raw) с командой zfs send передает зашифрованные блоки данных в целевой пул. Сырая отправка обеспечивает несколько преимуществ:
принимающая система никогда не видит данные в открытом виде.
принимающая система не требует кодовую фразу, поскольку расшифровка не выполняется.
Резервные копии можно отправлять без предварительной загрузки ключа шифрования.
Ненадёжная система может получить зашифрованные данные, но не может расшифровать или изменить их без ключа шифрования.
Чтобы отправить созданный выше снимок в виде необработанного потока в набор данных secret в пуле backup, введите следующую команду:
# zfs send -w zroot/secretdata@snap1 | zfs recv backup/secretБез опции -w команда zfs send передает данные в незашифрованном виде. Принимающая система затем может повторно зашифровать данные, используя другой ключ. Однако это предотвращает будущие инкрементальные «сырые» отправки на это место назначения.
23.6.7. Загрузка ключей шифрования при загрузке
Скрипт zfskeys из rc(8) загружает ключи шифрования при загрузке для зашифрованных наборов данных, чьё свойство keylocation указывает на файл ключа с URL-адресом file://. Скрипт запускается после импорта пула и перед монтированием файловых систем, поэтому наборы данных, обрабатываемые таким образом, монтируются автоматически во время обычного запуска ZFS. Скрипт не обрабатывает наборы данных с keylocation=prompt; загружайте их ключи вручную с помощью zfs load-key после загрузки системы.
Чтобы переключить набор данных, созданный ранее, с парольной фразы на файл ключа, сгенерируйте 32 байта случайных данных в качестве нового ключа, ограничьте доступ к файлу ключа и измените ключ шифрования набора данных:
# dd if=/dev/random of=/root/secretdata.key bs=32 count=1
# chmod 600 /root/secretdata.key
# zfs change-key -o keyformat=raw -o keylocation=file:///root/secretdata.key zroot/secretdataВключите скрипт в файле /etc/rc.conf:
# sysrc zfskeys_enable="YES"По умолчанию сценарий загружает ключи всех зашифрованных наборов данных с расположением ключей file://. Чтобы ограничить загрузку ключей конкретными наборами данных, перечислите их в zfskeys_datasets, разделяя пробелами:
# sysrc zfskeys_datasets="zroot/secretdata"Любой, кто может прочитать файл ключа, сможет расшифровать набор данных. Держите файл ключа принадлежащим |
23.7. Загрузочные окружения
Загрузочное окружение — это загрузочный клон дерева наборов данных, которое содержит операционную систему. На системах, установленных с раскладкой Root-on-ZFS, эти наборы данных находятся в zroot/ROOT, а работающая система — в zroot/ROOT/default. Создание загрузочного окружения создаёт снимки и клоны корневых наборов данных, что занимает секунды и почти не потребляет места на диске, пока окружения не начнут расходиться.
Управление загрузочными окружениями с помощью bectl(8). Создайте новое окружение перед серьезным изменением, таким как обновление операционной системы или крупного пакета:
# bectl create beforeupgrade
# bectl list
BE Active Mountpoint Space Created
default NR / 2.43G 2026-07-11 11:26
beforeupgrade - - 328K 2026-07-11 11:31В столбце Active метка N обозначает окружение, используемое в данный момент, а R — то, которое станет активным после перезагрузки.
Выполните обновление с помощью freebsd-update(8) или pkg(8) как обычно. Обновление изменяет активное окружение, тогда как beforeupgrade сохраняет систему в её прежнем состоянии. Если обновлённая система не загружается или работает некорректно, перезагрузитесь и выберите beforeupgrade из меню Boot Environments загрузчика FreeBSD. Выбор окружения в меню загрузчика влияет только на текущую загрузку. Чтобы сделать откат постоянным, активируйте это окружение:
# bectl activate beforeupgradeВыполнение bectl activate -t beName вместо этого активирует окружение только для следующей загрузки, что полезно при тестировании изменений на удаленной системе.
Чтобы осмотреть или восстановить содержимое неактивного окружения без его загрузки, смонтируйте его во временное расположение:
# bectl mount beforeupgrade
/tmp/be_mount.c1Xk
# bectl umount beforeupgradeУничтожьте окружение, которое больше не нужно, чтобы освободить занимаемое окружением пространство:
# bectl destroy beforeupgradeСоздание загрузочного окружения перед каждым freebsd-update(8) upgrade или крупной операцией pkg(8) обеспечивает мгновенный способ вернуться к заведомо исправной системе без восстановления из резервных копий. |
23.7.1. Загрузочные окружения и приложения
Загрузочное окружение содержит только наборы данных в zroot/ROOT. В стандартной компоновке Root-on-ZFS это включает всю корневую файловую систему с /usr/local и /var/db, поэтому установленные пакеты и их метаданные откатываются вместе с операционной системой. Наборы данных за пределами zroot/ROOT, такие как zroot/home, zroot/var/log и zroot/var/mail, являются общими: каждое окружение видит одни и те же файлы, и активация более старого окружения не возвращает их в более раннее состояние.
Спланируйте структуру набора данных с учётом этого разделения до того, как полагаться на загрузочные окружения. Данные, которые должны пережить откат, например базы данных приложения, установленного из пакетов, должны находиться в собственном наборе данных вне zroot/ROOT:
# zfs create -o mountpoint=/var/db/postgres zroot/pgdataПри такой компоновке откат к более старой среде возвращает бинарные файлы сервера баз данных к их предыдущей версии, в то время как содержимое базы данных остается нетронутым. Обратное также верно: файлы, записанные в общие наборы данных при тестировании новой среды, сохраняются после переключения обратно, поэтому загрузочные среды не заменяют снимки этих наборов данных.
23.8. Сложные темы
23.8.1. Настройка
Отрегулируйте параметры настройки, чтобы ZFS показывал наилучшую производительность для различных рабочих нагрузок. FreeBSD предоставляет параметры ядра ZFS как переменные sysctl(8) в разделе vfs.zfs; zfs(4) документирует каждый параметр и его значение по умолчанию. Установите значения, которые должны применяться с момента загрузки, в /boot/loader.conf; изменяйте значения, доступные для изменения во время работы, с помощью sysctl(8) и сделайте их постоянными в /etc/sysctl.conf.
vfs.zfs.arc.max— верхний размер ARC. Значение по умолчанию0позволяет ZFS автоматически определять размер ARC на основе объёма установленной оперативной памяти. Используйте меньшее значение, если в системе работают другие демоны или процессы, которым может потребоваться память. Смотрите «Размер и мониторинг ARC» для получения информации. Изменяйте это значение во время работы с помощью sysctl(8) и задавайте его в /boot/loader.conf или /etc/sysctl.conf.vfs.zfs.arc.min— нижний размер ARC. Значение по умолчанию0позволяет ZFS автоматически выбирать небольшое минимальное значение. Увеличьте это значение, чтобы предотвратить вытеснение всего ARC другими приложениями. Настройка этого значения возможна во время выполнения с помощью sysctl(8), а также в /boot/loader.conf или /etc/sysctl.conf.vfs.zfs.arc.meta_balance— баланс между кэшированием метаданных и данных файлов в ARC; значения выше100всё больше отдают предпочтение метаданным, по умолчанию —500. Увеличьте это значение, если рабочая нагрузка связана с операциями над большим количеством файлов и каталогов или частыми операциями с метаданными, ценой уменьшения объёма данных файлов, помещающихся в ARC. Этот настраиваемый параметр заменяетvfs.zfs.arc.meta_limit, который был удалён в OpenZFS 2.2. Изменяйте это значение в любое время с помощью sysctl(8).vfs.zfs.vdev.min_auto_ashift- Минимальное значениеashift(размер сектора), автоматически используемое при создании пула. Значение является степенью двойки. Значение по умолчанию9соответствует2^9 = 512, то есть размеру сектора 512 байт. Чтобы избежать усиления записи (write amplification) и получить наилучшую производительность, установите это значение равным наибольшему размеру сектора среди устройств в пуле.См. Создание и уничтожение пулов хранения о том, почему пулы на дисках с секторами 4 КБ должны использовать
ashiftсо значением 12.vfs.zfs.prefetch.disable— Отключает предварительную выборку. Значение0включает её, а1отключает. По умолчанию используется0. Предварительная выборка работает, считывая блоки большего размера, чем запрошено, в раздел ARC, в надежде, что данные скоро понадобятся. Если рабочая нагрузка включает большое количество случайных чтений, отключение предварительной выборки может улучшить производительность, сократив ненужные чтения. Это значение можно изменить в любое время с помощью sysctl(8).vfs.zfs.txg.timeout— Максимальное количество секунд между группами транзакций. Текущая группа транзакций записывается в пул, и начинается новая группа транзакций, если с момента предыдущей группы транзакций прошло указанное время. Группа транзакций может запуститься раньше при записи достаточного объёма данных. Значение по умолчанию составляет 5 секунд. Увеличение этого значения может улучшить производительность чтения за счет задержки асинхронных записей, но это может привести к неравномерной производительности при записи группы транзакций. Это значение можно изменить в любое время с помощью sysctl(8).vfs.zfs.l2arc.write_max— Ограничивает объём данных, записываемых в L2ARC в секунду. Этот параметр увеличивает срок службы SSD, ограничивая объём данных, записываемых на устройство. Значение можно изменить в любой момент с помощью sysctl(8).vfs.zfs.l2arc.write_boost— Добавляет значение этого параметра кvfs.zfs.l2arc.write_maxи увеличивает скорость записи на SSD до вытеснения первого блока из L2ARC. Эта "Фаза турборазогрева" снижает потерю производительности из-за пустого L2ARC после перезагрузки. Значение можно изменить в любое время с помощью sysctl(8).vfs.zfs.l2arc.rebuild_enabled- Обеспечивает сохранение содержимого L2ARC при перезагрузках. При значении по умолчанию1, ZFS перестраивает L2ARC из журнальных блоков, хранящихся на устройстве кэша, при импорте пула, избегая длительного периода прогрева, который потребовался бы пустому кэшу. Установите это значение в0, чтобы всегда начинать с пустого L2ARC.vfs.zfs.vdev.max_active— максимальное количество активных запросов ввода-вывода на каждом устройстве в пуле. Более высокое значение поддерживает очередь команд устройства заполненной и может увеличить пропускную способность. Более низкое значение уменьшает задержки. Это значение можно изменить в любое время с помощью sysctl(8).vfs.zfs.vdev.*_min_activeиvfs.zfs.vdev.*_max_active— нижний и верхний предел количества одновременных запросов ввода-вывода, которые планировщик отправляет каждому устройству для каждого класса ввода-вывода:sync_read,sync_write,async_read,async_write,scrubи других. Эти ограничения для каждого класса заменяют основанное на задержках ограничение scrub и resilver, которое использовалось в более старых версиях ZFS. Например, увеличениеvfs.zfs.vdev.scrub_max_activeпозволяет операциям проверки (scrub) использовать большую долю очереди каждого устройства, завершаясь быстрее за счет увеличения задержки операций ввода-вывода переднего плана.`vfs.zfs.resilver_min_time_ms`_ — минимальное количество времени в миллисекундах, которое resilver тратит на работу между сбросами групп транзакций; по умолчанию равно
3000(3 секунды). Увеличьте это значение, чтобы завершить процесс восстановления (resilver) быстрее, когда деградировавший пул находится под угрозой потери другого устройства, ценой замедления нормальной работы пула. Изменяйте это значение в любое время с помощью sysctl(8).
23.8.2. Определение размера ARC и мониторинг
ZFS хранит недавно и часто используемые данные и метаданные в оперативной памяти в ARC. ARC растет по мере необходимости до vfs.zfs.arc.max и снова уменьшается, когда другим программам нужна память, поэтому на выделенном сервере хранения нормально, что большая часть оперативной памяти используется. ARC хранит блоки в их сжатом виде на диске и распаковывает их при доступе. Этот сжатый ARC позволяет тому же объему оперативной памяти кэшировать больше данных, увеличивая эффективную частоту попаданий.
top(1) отображает текущий размер ARC в строке сводки по памяти. Дерево kstat.zfs.misc.arcstats из sysctl(8) предоставляет подробную статистику, включая текущий размер, целевой максимум, а также счетчики попаданий и промахов:
% sysctl kstat.zfs.misc.arcstats.size kstat.zfs.misc.arcstats.c_max kstat.zfs.misc.arcstats.hits kstat.zfs.misc.arcstats.misses
kstat.zfs.misc.arcstats.size: 8963041280
kstat.zfs.misc.arcstats.c_max: 15843122176
kstat.zfs.misc.arcstats.hits: 954912441
kstat.zfs.misc.arcstats.misses: 21356847filesystems/zfs-stats обобщает эти статистические данные в удобочитаемом отчете.
ARC возвращает память при нехватке ресурсов, но на системах, где ОЗУ разделяется между ZFS и другими крупными потребителями, такими как базы данных, виртуальные машины или клетки, конкуренция может вызывать неравномерную производительность с обеих сторон. Ограничение ARC оставляет предсказуемый объём памяти для других рабочих нагрузок. Например, чтобы ограничить ARC до 8 ГБ, добавьте эту строку в /boot/loader.conf:
vfs.zfs.arc.max="8G"
Изменение vfs.zfs.arc.max с помощью sysctl(8) вступает в силу немедленно, хотя уменьшение теплого ARC освобождает память постепенно.
23.8.3. Синхронные записи, ZIL и SLOG
Каждый пул имеет ZIL. Приложения, запрашивающие синхронную семантику с помощью fsync(2) или флага O_SYNC, не получают подтверждение до тех пор, пока ZFS не зафиксирует соответствующую запись журнала намерений в стабильном хранилище. По умолчанию ZIL располагается на обычных vdev пула, поэтому каждая синхронная запись конкурирует с обычным вводом-выводом пула. Асинхронные записи обходят ZIL и записываются со следующей транзакционной группой.
Выделенный перекрестная ссылка:zfs[zfs-term-vdev-log,log] vdev, часто называемый SLOG (отдельный журнал), перемещает ZIL на быстрое устройство:
# zpool add mypool log mirror nda0 nda1SLOG помогает только рабочим нагрузкам, которые генерируют много синхронных записей, например, NFS-серверам и базам данных. Для чисто асинхронных рабочих нагрузок он не имеет значения.
Несколько гигабайт ёмкости SLOG вполне достаточно: ZIL хранит максимум несколько секунд входящих записей, примерно объём одной группы транзакций, прежде чем ZFS запишет данные в их конечное расположение в пуле. Выбирайте SSD с защитой от потери питания и низкой задержкой устойчивой записи, а также зеркалируйте устройства журнала. ZFS читает ZIL только после сбоя, поэтому потеря незеркалированного SLOG вместе со сбоем системы приводит к потере записей, которые были подтверждены, но ещё не зафиксированы в пуле.
Свойство sync набора данных управляет поведением синхронной записи:
sync=standard(по умолчанию) фиксирует синхронные записи в ZIL, а асинхронные записи — со следующей группой транзакций.sync=alwaysобрабатывает каждую запись как синхронную, жертвуя производительностью ради безопасности, которая помогает только приложениям, которые не запрашивают синхронные записи, когда это необходимо.sync=disabledобрабатывает каждую запись как асинхронную.
С |
Свойство logbias регулирует, как ZFS использует журнал: logbias=latency (по умолчанию) предпочитает SLOG для минимизации задержки фиксации, тогда как logbias=throughput записывает синхронные данные напрямую в основной пул, оставляя ёмкость SLOG для наборов данных, чувствительных к задержке. Подробности см. в zfsprops(7).
23.8.4. Прямой ввод-вывод
Прямой ввод-вывод требует OpenZFS 2.3 или более поздней версии, впервые доступной в FreeBSD 15.0. |
Свойство набора данных direct управляет тем, как ZFS обрабатывает запросы, сделанные с флагом O_DIRECT:
direct=standard(по умолчанию) учитываетO_DIRECT: корректно выровненные чтения и записи обходят ARC.direct=alwaysобрабатывает каждое правильно выровненное чтение или запись как прямой запрос.direct=disabledбеззвучно игнорируетO_DIRECTи обрабатывает каждый запрос через ARC.
Прямой ввод-вывод позволяет избежать копирования в памяти и накладных расходов на кэширование ARC. В пулах очень быстрых NVMe-устройств эти накладные расходы могут доминировать над стоимостью самого ввода-вывода, а приложения, поддерживающие собственные кэши, например базы данных, тратят оперативную память впустую, кэшируя одни и те же данные дважды. Для таких рабочих нагрузок прямой ввод-вывод может увеличить пропускную способность и снизить использование памяти.
ZFS по-прежнему проверяет контрольные суммы для прямых чтений и записей, поэтому защита целостности данных не изменяется. Прямые записи должны быть выровнены по значению recordsize набора данных; ZFS незаметно перенаправляет невыровненную часть запроса через ARC. См. zfsprops(7) для получения полных правил и ограничений по выравниванию.
23.8.5. recordsize и volblocksize
Свойство recordsize задаёт наибольший блок, который ZFS использует для хранения файла в наборе данных, по умолчанию 128 КБ. Согласование размера блока с шаблоном ввода-вывода рабочей нагрузки позволяет избежать чтения и записи большего объёма данных, чем запрашивает приложение.
Для баз данных, выполняющих небольшие случайные чтения и записи, установите recordsize равным размеру страницы базы данных, обычно 8 КБ или 16 КБ, до создания файлов базы данных. Для наборов данных, хранящих большие медиафайлы или потоки резервных копий, которые читаются и записываются последовательно, recordsize=1M снижает накладные расходы на метаданные и улучшает сжатие. Тома используют свойство volblocksize вместо этого, которое по умолчанию составляет 16 КБ и не может быть изменено после создания тома.
Изменение recordsize влияет только на новые записанные файлы; существующие файлы сохраняют свой исходный размер блока. Даже zfs rewrite не применяет новое значение recordsize к существующим файлам, поскольку изменения свойств, влияющие на логический размер блока, не действуют на перезаписанные блоки; скопируйте файлы заново, чтобы сохранить их с новым значением.
23.9. Дополнительные ресурсы
Документация OpenZFS, включая руководства по производительности и настройке
zfs(4) описывает каждый настраиваемый параметр ядра, zpoolconcepts(7) описывает типы vdev и структуру пула, а zfsprops(7) описывает каждое свойство набора данных
Инструменты автоматизации снимков и репликации из коллекции портов:
filesystems/zrepl - демон репликации, поддерживающий конфигурации push и pull, автоматическое управление снимками и возобновляемые передачи
sysutils/sanoid — управление снимками на основе политик, с входящим в комплект
syncoidдля репликации по SSHfilesystems/zfstools - автоматическая ротация снимков в стиле службы автоматических снимков OpenSolaris, запускаемая из cron(8)
filesystems/zap - простое обслуживание снапшотов и удаленная репликация, настраиваемое через свойства ZFS вместо файла конфигурации
23.10. Особенности и терминология ZFS
ZFS принципиально отличается от традиционных файловых систем. ZFS объединяет функции файловой системы и менеджера томов, позволяя добавлять новые устройства хранения в работающую систему и сразу же использовать новое пространство в существующих файловых системах пула. Благодаря объединению традиционно разделённых ролей, ZFS преодолевает прежние ограничения, которые мешали расширению RAID-групп. Устройство vdev — это устройство верхнего уровня в пуле, которое может быть простым диском или RAID-преобразованием, таким как зеркало или массив RAID-Z. Файловые системы ZFS (называемые наборами данных) имеют доступ к объединённому свободному пространству всего пула. Используемые блоки из пула уменьшают доступное пространство для каждой файловой системы. Такой подход позволяет избежать распространённой проблемы с разбиением на разделы, когда свободное пространство фрагментируется между разделами.
Пул (pool) — это базовая строительная единица ZFS. Оно состоит из одного или нескольких vdev — устройств хранения данных. На основе хранилища создаются файловые системы (наборы данных, datasets) или блочные устройства (тома, volumes). Эти наборы данных и тома используют общий пул свободного пространства. Каждый пул имеет уникальное имя и GUID. Пулы, созданные современной OpenZFS, имеют версию пула 5000; начиная с этой версии, отдельные возможности управляются с помощью функциональных флагов (feature flags), а не номера версии. Подробнее см. zpool-features(7) и «Обновление пула хранения». | |||||
Пул состоит из одного или нескольких vdev, которые, в свою очередь, представляют собой отдельный диск или группу дисков, преобразованных в RAID. При использовании множества vdev ZFS распределяет данные между ними для повышения производительности и максимизации доступного пространства. Все vdev должны быть размером не менее 64 МБ.
| |||||
Группы транзакций — это способ, которым ZFS объединяет изменения блоков и записывает их в пул. Группы транзакций являются атомарной единицей, используемой ZFS для обеспечения согласованности. ZFS назначает каждой группе транзакций уникальный 64-битный последовательный идентификатор. Одновременно может быть до трёх активных групп транзакций, каждая в одном из следующих состояний: * Открытое (Open) — Новая группа транзакций начинается в открытом состоянии и
принимает новые операции записи. Всегда существует группа транзакций
в открытом состоянии, но она может отказать в приёме новых записей,
если достигнут лимит. Как только открытая группа транзакций достигает
лимита или срабатывает | |||||
ZFS использует Adaptive Replacement Cache (ARC), а не более традиционный кэш Least Recently Used (LRU). LRU-кэш — это простой список элементов в кэше, отсортированный по времени последнего использования объекта, при этом новые элементы добавляются в начало списка. Когда кэш заполнен, освобождение места для более активных объектов происходит за счёт удаления элементов из конца списка. ARC состоит из четырёх списков: Most Recently Used (MRU) и Most Frequently Used (MFU), а также дополнительных "теневых" списков для каждого из них. Эти теневые списки отслеживают удалённые объекты, чтобы предотвратить их повторное добавление в кэш. Это увеличивает процент попаданий в кэш, исключая объекты, которые использовались лишь изредка. Ещё одно преимущество использования как MRU, так и MFU заключается в том, что сканирование всей файловой системы вытеснило бы все данные из MRU- или LRU-кэша в пользу только что прочитанного содержимого. В ZFS также присутствует MFU, который отслеживает наиболее часто используемые объекты, и кэш наиболее часто запрашиваемых блоков остаётся неизменным. | |||||
L2ARC — это второй уровень системы кэширования ZFS. Основной кэш (ARC) хранится в оперативной памяти.
Поскольку объём доступной оперативной памяти часто ограничен, ZFS также может использовать
кэширующие vdev.
Твердотельные накопители (SSD) часто используются в качестве
таких кэширующих устройств благодаря их более высокой скорости и меньшей задержке по сравнению
с традиционными жёсткими дисками.
L2ARC полностью опционален, но его наличие увеличит скорость чтения
для кэшированных файлов на SSD, избавляя от необходимости читать с обычных дисков.
L2ARC также может ускорить дедупликацию, поскольку таблица дедупликации (DDT - deduplication table),
которая не помещается в оперативную память, но помещается в L2ARC, будет работать значительно быстрее,
чем DDT, которую должны считать с диска.
Начиная с OpenZFS 2.0, L2ARC является постоянным: после перезагрузки ZFS восстанавливает содержимое кэша из заголовков, хранящихся на кэширующем устройстве, вместо того чтобы начинать с пустого кэша.
Ограничения на скорость записи данных
на кэширующие устройства предотвращают преждевременный износ SSD из-за дополнительных операций записи. Пока кэш не заполнен (первый блок вытеснен для освобождения места),
записи в L2ARC ограничиваются суммой лимита записи и лимита ускорения, а после - только лимитом записи.
Пара значений sysctl(8) управляет этими ограничениями скорости. | |||||
Журнал намерений ZFS (ZIL) — это запись на диске, которую ZFS использует для воспроизведения синхронных записей после сбоя. Каждый пул имеет ZIL; по умолчанию он занимает небольшой объём пространства на обычных устройствах пула. Когда приложение запрашивает синхронную запись (гарантию того, что данные сохранены на диске, а не просто закэшированы для последующей записи), ZFS сначала фиксирует данные в ZIL, а затем сбрасывает их в обычное хранилище со следующей группой транзакций. Перемещение ZIL на выделенное журнальное виртуальное устройство (SLOG) на устройстве, более быстром, чем основное хранилище, например SSD, значительно снижает задержку и повышает производительность. Синхронные рабочие нагрузки, такие как базы данных, выиграют от одного только быстрого ZIL. Обычные асинхронные записи, например копирование файлов, вообще не используют ZIL. Подробнее см. Синхронные записи, ZIL и SLOG. | |||||
В отличие от традиционной файловой системы, ZFS записывает новый блок вместо перезаписи старых данных на том же месте. После завершения записи метаданные обновляются, указывая на новое местоположение. Если происходит обрыв записи (сбой системы или отключение питания во время записи файла), исходное содержимое файла остаётся доступным, а ZFS отменяет незавершённую запись. Это также означает, что ZFS не требует выполнения fsck(8) после неожиданного выключения. | |||||
Набор данных — это общий термин для файловой системы ZFS, тома, снимка или клона. Каждый набор данных имеет уникальное имя в формате имяпула/путь@снимок. Корень пула также является набором данных. Дочерние наборы данных имеют иерархические имена, подобные каталогам. Например, mypool/home, набор данных home, является дочерним для mypool и наследует его свойства. Это можно расширить, создав mypool/home/user. Этот внучатый набор данных будет наследовать свойства от родительского и вышестоящего наборов данных. Установка свойств для дочернего набора данных позволяет переопределить значения по умолчанию, унаследованные от родительских наборов. Управление наборами данных и их дочерними элементами может быть делегировано. | |||||
Набор данных ZFS чаще всего используется как файловая система. Как и большинство других файловых систем, файловая система ZFS монтируется в определённое место иерархии каталогов системы и содержит собственные файлы и каталоги с правами доступа, флагами и другими метаданными. | |||||
ZFS также может создавать тома, которые отображаются как дисковые устройства. Тома обладают многими функциями, аналогичными наборам данных, включая копирование при записи, снимки, клоны и контрольные суммы. Тома могут быть полезны для работы других файловых систем поверх ZFS, таких как виртуализация UFS или экспорт областей iSCSI. | |||||
Дизайн copy-on-write (COW) в ZFS позволяет создавать почти мгновенные, согласованные снимки с произвольными именами. После создания снимка набора данных или рекурсивного снимка родительского набора, который включит все дочерние наборы, новые данные записываются в новые блоки, но без освобождения старых блоков как свободного пространства. Снимок содержит исходную версию файловой системы, а активная файловая система — все изменения, сделанные после создания снимка, не используя дополнительного пространства. Новые данные, записанные в активную файловую систему, сохраняются в новых блоках. Снимок будет расти по мере того, как блоки перестают использоваться в активной файловой системе и остаются только в снимке. Монтирование этих снимков в режиме только для чтения позволяет восстановить предыдущие версии файлов. Откат активной файловой системы к определённому снимку возможен, отменяя все изменения, произошедшие после создания снимка. Каждый блок в пуле имеет счетчик ссылок, который отслеживает использование этого
блока снимками, клонами, наборами данных или томами. По мере удаления файлов и
снимков счетчик ссылок уменьшается, освобождая пространство, когда блок больше
не используется. Если пометить снимки с помощью
удержания (hold), то это приведет к тому, что любая попытка удалить его вернет ошибку | |||||
Также возможно клонирование снимка. Клон — это доступная для записи версия снимка, позволяющая файловой системе разветвляться как новый набор данных. Как и снимок, клон изначально не занимает дополнительного пространства. По мере записи новых данных в клон используются новые блоки, и размер клона увеличивается. При перезаписи блоков в клонированной файловой системе или томе счетчик ссылок на предыдущий блок уменьшается. Удалить снимок, на котором основан клон, невозможно, потому что клон зависит от него. Снимок является родителем, а клон — потомком. Клоны можно повышать, меняя эту зависимость местами, делая клон родителем, а предыдущего родителя — потомком. Эта операция не требует дополнительного пространства. Поскольку объём пространства, используемого родителем и потомком, меняется местами, это может повлиять на существующие квоты и резервирования. | |||||
Закладка фиксирует момент времени, в который был сделан снапшот, не сохраняя при этом никаких данных снапшота.
Закладки служат источником инкрементальных потоков | |||||
Удержание — это именованная метка, помещаемая на снимок, которая предотвращает его уничтожение.
Попытки уничтожить удерживаемый снимок завершаются с ошибкой | |||||
Каждый блок также имеет контрольную сумму. Используемый алгоритм контрольной суммы
является свойством для каждого набора данных, см. Алгоритмы | |||||
Каждый набор данных имеет свойство сжатия (compression). Начиная с OpenZFS 2.2, для новых наборов данных сжатие включено по умолчанию ( * LZ4 — добавлен в версии 5000 (флаги функций) пула ZFS, LZ4 — это алгоритм, который выбирается параметром * ZSTD — Zstandard обеспечивает более высокую степень сжатия, чем LZ4, с настраиваемым компромиссом между скоростью и степенью сжатия, начиная от быстрых вариантов * LZJB — устаревший алгоритм сжатия, создан Джеффом Бонвиком (одним из первоначальных создателей ZFS). LZJB обеспечивает хорошее сжатие с меньшей нагрузкой на CPU по сравнению с GZIP. LZ4 заменил его в качестве алгоритма по умолчанию, для новых наборов данных предпочитайте LZ4 или ZSTD. * GZIP — популярный алгоритм потокового сжатия, доступный в ZFS. Одним из основных преимуществ использования GZIP является настраиваемый уровень сжатия. При установке свойства * ZLE — Zero Length Encoding (кодирование нулевой длины) — это специальный алгоритм сжатия, который сжимает только непрерывные последовательности нулей. Этот алгоритм полезен, когда набор данных содержит большие блоки нулей. | |||||
Когда свойству | |||||
Контрольные суммы позволяют обнаруживать дублирующиеся блоки при записи данных. При дедупликации счетчик ссылок существующего идентичного блока увеличивается, что экономит место на диске. ZFS хранит таблицу дедупликации (DDT) в памяти для обнаружения дублирующихся блоков. Таблица содержит список уникальных контрольных сумм, расположение этих блоков и счетчик ссылок. При записи новых данных ZFS вычисляет контрольные суммы и сравнивает их со списком. При обнаружении совпадения используется существующий блок. Использование алгоритма контрольной суммы SHA256 с дедупликацией обеспечивает безопасное криптографическое хеширование. Дедупликация настраивается. Если | |||||
Блочное клонирование позволяет копии файла ссылаться на блоки исходного файла, существующие на диске, вместо их дублирования, поэтому копия выполняется почти мгновенно и не занимает дополнительное место, пока ни один из файлов не изменится.
На FreeBSD cp(1) использует copy_file_range(2), поэтому обычные копии файлов становятся блочными клонами, когда эта функция включена (по умолчанию в FreeBSD 15.0).
Свойства пула | |||||
Вместо проверки согласованности, такой как fsck(8), в ZFS используется | |||||
Контрольная точка сохраняет полное состояние пула в единый момент времени, включая изменения конфигурации всего пула, которые снимки не могут зафиксировать.
Возврат к контрольной точке с помощью | |||||
TRIM уведомляет SSD и другие накопители на флеш-памяти о блоках, которые пул больше не использует, позволяя устройству заранее стирать их и поддерживать производительность записи.
Запустите | |||||
ZFS обеспечивает быстрый и точный учёт пространства для наборов данных, пользователей и групп, а также квоты и резервирование пространства. Это даёт администратору детальный контроль над распределением пространства и позволяет резервировать место для критически важных файловых систем. ZFS поддерживает различные типы квот: квоту набора данных, референтную квоту (refquota), пользовательскую квоту и групповую квоту. Квоты ограничивают общий размер набора данных и его потомков, включая снимки набора данных, дочерние наборы данных и снимки этих наборов данных.
| |||||
Референтная квота ограничивает объём пространства, который может занимать набор данных, устанавливая жёсткий лимит. Этот жёсткий лимит включает только пространство, на которое ссылается сам набор данных, и не учитывает пространство, используемое его потомками, такими как файловые системы или снимки. | |||||
Пользовательские квоты полезны для ограничения объёма пространства, используемого указанным пользователем. | |||||
Квота группы ограничивает объём пространства, который может использовать указанная группа. | |||||
Свойство | |||||
Свойство | |||||
Загрузочное окружение — это загрузочная копия наборов данных, содержащих систему FreeBSD, управляемая с помощью bectl(8). Создание загрузочного окружения перед обновлением системы позволяет загрузить предыдущую, заведомо рабочую систему из меню загрузчика, если обновление вызовет проблемы. Подробности см. в Загрузочные окружения. | |||||
При замене вышедшего из строя диска ZFS должен заполнить новый диск утерянными данными.
Ресилверинг — это процесс записи этих данных на заменяющее устройство: зеркала выполняют ресилверинг путём копирования данных с выживших участников, а RAID-Z восстанавливает их из информации о чётности, распределённой по оставшимся дискам.
В отличие от традиционной перестройки RAID, ресилверинг копирует только выделенные данные, а не каждый сектор устройства.
Последовательный ресилверинг ( | |||||
Пул или vdev в состоянии | |||||
Администратор переводит отдельные устройства в состояние | |||||
Пул или vdev в состоянии | |||||
Пул или vdev в состоянии | |||||
Устройство в состоянии | |||||
Устройство в состоянии |
Изменено: 12 августа 2026 г. by Vladlen Popolitov