Глава 4. Наборы данных ZFS

Содержание

4. Наборы данных ZFS
Наборы данных
Типы наборов данных
Зачем мне нужны наборы данных?
Просмотр наборов данных
Создание, перемещение и ликвидация наборов данных
Создание файловых систем
Создание томов
Переименование наборов данных
Перемещение наборов данных
Ликвидация наборов данных
Свойства ZFS
Просмотр свойств
Изменение свойств
Свойства, доступные только для чтения
Свойства файловой системы
atime
exec
readonly
setuid
Определяемые пользователем свойства
Взаимосвязи родительский/ дочерний
Наследование и переименование
Удаление свойств
Монтирование файловых систем ZFS
Наборы данных без точки монтирования
Множественные наборы данных с одной и той же точкой монтирования
Пулы без точки монтирования
Монтирование и демонтирование файловых систем вручную
ZFS и /etc/fstab
Тонкая настройка томов ZFS
Резервирование пространства
Режим Zvol
Целостность наборов данных
Контрольные суммы
Копии
Избыточность метаданных

В обычных файловых системах вы создаете разделы для разделения различных типов данных, применения различных видов оптимизации для них, а также для ограничения в объеме пространства, который может потреблять данный раздел. Каждый раздел получает определенный объем дискового пространства. Вы все бывали на этом месте. Мы делаем наши лучшие догадки о том, как много дискового пространства понадобится в следующем месяце, следующем году, и через пять лет каждому разделу в данной системе. Быстро перенесемся в будущее и окажется, что объем пространства, которое вы решили выделить каждому разделу скорее всего не правильный. Раздел без достаточного пространства для всех его данных извещает вас о добавлении дисков или перемещении данных, усложняя управление системой. Когда раздел имеет слишком много пространства вы пеняете на себя и используете его в качестве свалки для хлама, который вы предпочли бы иметь в другом месте. Не одна система UFS2 Лукаса имеет /usr/ports в качестве символической ссылки на что- то в /home. Джуд обычно получает в конце концов какую- либо часть /var, проживающую в /usr/local/var

ZFS решает эту проблему собирая свободное пространство в пулы, привнося в ваше разбиение на разделы гибкость, невозможную для большинства других файловых систем. Каждый создаваемый вами набор данных ZFS потребляет только объем пространства, необходимый для хранения файлов внутри него. Каждый набор данных имеет доступ ко всему свободному пространству в данном пуле прекращая ваше беспокойство о размере вашего раздела. Вы можете ограничить размер набора данных при помощи квотирования или гарантировать ему минимальный объем пространства путем резервирования, как это обсуждается в Главе 6.

Обычные файловые системы используют отдельные разделы для установления различных политики оптимизации для различных типов данных. /var содержит часто изменяемые файлы наподобие журналов и баз данных. Корневой файловой системе, помимо производительности, нужны согласованность и безопасность. В /home попадает все что угодно. Однако, после установления политики для традиционной файловой системы, действительно трудно вносить изменения. Утилита tunefs(8) для UFS требует размонтирования файловой системы для внесения изменений. Некоторые характеристики, например количество индексных дескрипторов, просто не могут быть изменены после создания файловой системы.

Основная проблема традиционных файловых систем перегоняется в негибкость. Наборы данных ZFS практически бесконечно гибки.

 Наборы данных

Порции данных называются наборами данных (dataset). Эти данные могут напоминать традиционную файловую систему с файлами, каталогами, а также допусками и всем, что радует персонал. Это может быть блочное устройство или копия других данных, или что-то что вы сможете впихнуть на диск.

ZFS использует наборы данных во многом подобно тому, как традиционная файловая система может использовать разделы. Нужна некая политика для /usr и отдельная политика для /home? Сделайте каждый из них набором данных. Нужно блочное устройство для приемника iSCSI? Это набор данных. Нужна копия какого-то набора данных? Это другой набор данных.

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

Вы можете выполнять все операции с наборами данных воспользовавшись командой zfs(8). Данная команда имеет все виды подкоманд.

  Типы наборов данных

В настоящее время ZFS имеет пять типов наборов данных: файловые системы, тома, снимки, клоны и закладки.

Набор данных filesystem повторяет традиционную файловую систему. Он хранит файлы и каталоги. Файловая система ZFS имеет точку монтирования и поддерживает свойства традиционных файловых систем, такие как доступность только на чтение, исполняемые файлы с ограничением на setuid {повышение прав до уровня владельца} и другие. Наборы данных файловой системы также содержат другую информацию, включающую права доступа, временные метки создания и изменения файла, флаги управления доступом NFSv4, chflags(2) и тому подобное.

Том ZFS, или zvol является блочным устройством. В обычной файловой системе вы можете создать файловую систему на основе файловой системы для iSCSI или раздела UFS со специальным назначением. В ZFS эти блочные устройства обходят все накладные расходы файлов и каталогов и располагаются непосредственно в основном пуле. Zvol получает файл устройства (device node), пропуская устройства памяти данной FreeBSD, используемые для монтирования образов дисков.

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

Clone является новым набором данных основанном на снимке существующего набора данных, позволяющий вам разветвлять файловую систему. Вы получаете дополнительную копию всего в данном наборе данных. Вы можете клонировать набор данных, содержащий ваш промышленный веб- сайт, предоставляя вам копию вашего сайта, которую ломать без боязни задеть промышленный сайт. Клон потребляет только пространство для хранения приращений от первоначального снимка, из которого он создан. Глава 7 обсуждает снимки, клоны и закладки.

  Зачем мне нужны наборы данных?

Очевидно, вам нужны наборы данных. Помещение файлов на диск требует набора данных файловой системы. И вам, вероятно, потребуется по набору данных для традиционных разделов Unix, наподобие /usr или /var. Однако, в ZFS вы хотите много наборов данных. Много- много- много- данных. Это было бы беспощадным безумием в традиционной файловой системе с жестко заданными ограничениями на число разделов и негибкость этих разделов. Однако применение большого числа наборов данных увеличивает имеющийся у вас контроль над данными.

Каждый набор данных ZFS имеет ряд свойств, которые управляют его работой, позволяя администратору контролировать то как представляются наборы данных и насколько тщательно они защищают свои данные. Вы можете подстраивать каждый набор данных в точности так, как вы можете в обычной файловой системе. Свойства наборов данных работают во многом похоже на свойства пула.

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

Многие свойства ZFS, такие как репликации и снимки работают на базе отдельных наборов данных. Выделение ваших данных в одну логическую группу облегчает применение этих свойств для сопровождения вашей организации.

Возьмем к примеру веб- сервер с десятками сайтов, причем каждый поддерживается отдельной командой. Некоторые команды отвечают за несколько сайтов, в то время как остальные имеют только один. Некоторые команды относятся ко многим командам. Если вы будете следовать традиционной модели файловой системы, вы можете создать набор данных /webserver поместите в него все и управляйте доступом при помощи групповых прав доступа и команды sudo(8). Вы жили так на протяжении десятилетий и это работает, так зачем все менять?

Однако создание набора данных для каждой команды, а затем предоставление каждому сайту его собственного набора данных в пределах данного родительского набора данных, и возможности размножаются.

Команде нужна копия веб-сайта для тестирования? Клонируйте его! В традиционной файловой системе вам придется копировать весь каталог этого сайта, удваивая необходимое дисковое пространство и дожидаясь намного более длительного выполнения. Клон использует только пространство для разниц между сайтами и появляется мгновенно.

Команда собирается развернуть новую версию сайта, но хочет иметь резервную копию старого сайта? Создайте снимок. Этот новый сайт, вероятно, использует целую кучу тех же файлов, что и старый, так что вы сократите использование дискового пространства. Плюс, когда развертывание идет ужасно неправильно, можно восстановить старую версию откатив к снимку.

Определенному веб-сайту требуются хитрости производительности на уровне файловой системы, или сжатие, или какое-либо локально созданное свойство? Установите его для этого сайта.

Вы можете создать набор данных для каждой команды, а затем пусть команды создают свои собственные дочерние наборы данных для их собственных сайтов. Вы можете организовать ваши наборы данных, чтобы они соответствовали вашему персоналу, вместо организации ваших людей, чтобы они соответствовали вашей технологии.

Когда необходимо изменить настройки (свойства) файловой системы на всех этих сайтах, сделайте изменения в родительском наборе данных, и пусть дети наследуют их.

Те же преимущества распространяются на домашние каталоги пользователей.

Также вы можете перемещать данные между машинами. Ваши веб- сайты переполнили ваш веб- сайт? Отправьте на новый сервер половину наборов данных совместно с их пользовательскими настройками, а также с их клонами и снимками.

Существует один недостаток при использовании многих наборов данных файловых систем. Когда вы перемещаете файл в пределах файловой системы, файл переименовывается. Перемещение файла между различными файловыми системами требует копирование файла в новое местоположение и удаление его в старом, вместо простого его переименования. Копирование файла между наборами данных отнимает больше времени и требует больше свободного пространства. Однако это незначительно по сравнению со всеми преимуществами, которые дает вам ZFS посредством множественности наборов данных. Эта проблема также существует в других файловых системах, однако у хостов, использующих большинство других файловых систем есть только несколько разделов, что делает эту проблему менее очевидной.

 Просмотр наборов данных

Команда zfs list отображает все наборы данных и некоторую основную информацию о них.

# zfs list
NAME                 USED  AVAIL  REFER  MOUNTPOINT
mypool               420M  17.9G    96K  none
mypool/ROOT          418M  17.9G    96K  none
mypool/ROOT/default  418M  17.9G   418M  /
...
	   

Первое поле показывает иена наборов данных.

Под USED и REFER вы найдете информацию о том сколько дискового пространства использует набор данных. Одним из недостатков невероятной гибкости и эффективности ZFS является то, что интерпретация использования ей дискового пространства кажется несколько сюрреалистичной, если вы ее не понимаете. Глава 6 обсуждает дисковое пространство и стратегии его использования.

Колонка AVAIL отображает сколько пространства остается свободным в пуле или наборе данных.

Наконец, MOUNTPOINT показывает где должен быть смонтирован набор данных. Это не означает, что набор данных смонтирован, а только то, что если бы он был смонтирован, то это то место, где он должен быть. (Для просмотра всех смонтированных файловых систем ZFS воспользуйтесь zfs mount)

Если вы дадите набор данных в качестве аргумента, zfs list отобразит только этот определенный набор данных.

# zfs list mypool/lamb
NAME         USED  AVAIL  REFER  MOUNTPOINT
mypool/lamb  192K  17.9G    96K  /lamb
	   

Ограничьте отображаемый тип набор данных флагом -t и этим типом. Вы можете отображать filesystem, volume или snapshot. Вот мы отображаем снимки и только снимки.

# zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
zroot/var/log/db@backup  0         -  10.0G  -
	   

Теперь вы можете увидеть файловые системы, давайте посмотрим на некоторые.

 Создание, перемещение и ликвидация наборов данных

Воспользуйтесь командой zfs create для создания какого- либо набора данных. Мы рассмотрим снимки, клоны и закладки в Главе 7, а сейчас давайте рассмотрим файловые системы и тома.

  Создание файловых систем

Файловые системы являются наиболее общим типом набором данных для большинства систем. Всем требуется место для хранения и упорядочения файлов. Создайте набор данных файловой системы описав пул и имя файловой системы.

# zfs create mypool/lamb
	   

Это создает новый набор данных, lamb в пуле ZFS с именем mypool. Если этот пул имеет точку монтирования по умолчанию, новый набор данных монтируется в указанном месте по умолчанию. (см. "Монтирование файловых систем ZFS" далее в данной главе).

# mount | grep lamb
mypool/lamb on /lamb (zfs, local, noatime, nfsv4acls)
	   

Заключенные в скобки установки монтирования, как правило, являются свойствами ZFS, наследуемыми от родительского набора данных. Чтобы создать дочернюю файловую систему, задайте полный путь к родительской файловой системе.

# zfs create mypool/lamb/baby
	   

Набор данных наследует многие из своих свойств, включая свою точку монтирования, от родителя, как мы увидим позже в "Взаимосвязи родительский/ дочерний" в данной главе.

  Создание томов

Воспользуйтесь флагом -V и размером тома для сообщения zfs create того, что вы хотите создать том. Задайте полный путь к набору данных тома.

# zfs create -V 4G mypool/avolume
	   

Zvol отображаются в списке наборов данных наряду с любыми другими наборами данных. Вы можете попросить zfs list отображать только zvol добавив параметр -t volume.

# zfs list mypool/avolume
NAME            USED   AVAIL  REFER  MOUNTPOINT
mypool/avolume  4.13G  17.9G    64K  -
	   

Zvol автоматически резервирует объем пространства эквивалентный размеру тома плюс метаданные ZFS. Данный zvol с 4ГБ использует 4.13ГБ пространства.

Будучи блочным устройством, zvol не имеют точки монтирования. Они получают файл устройства (device node) в /dev/zvol, следовательно вы можете осуществлять к ним доступ, как вы это делаете с любым другим блочным устройством.

# ls -al /dev/zvol/mypool/avolume
crw-r----- 1 root operator 0x4d Mar 27 20:22 /dev/zvol/mypool/avolume
	   

Вы можете выполнить newfs(8) в этом файле устройства (device node), скопировать в нее образ диска и применять ее обычным образом как любое другое блочное устройство.

  Переименование наборов данных

Вы можете переименовать набор данных, причем, как ни странно, командой zfs rename. Задайте имя текущего набора данных в качестве первого аргумента, а новое местоположение в качестве второго.

# zfs rename db/production db/old
# zfs rename db/testing db/production
	   

Применяйте флаг -f для принудительного переименования данного набора данных. Вы не можете размонтировать файловую систему с запущенными на ней процессами, однако флаг -f принудит размонтирование с ликованием. Все процессы, использующие этот набор данных потеряют любой используемый ими доступ и взаимодействуют как будто он все еще есть (вероятно, не лучшим образом).

  Перемещение наборов данных

Вы можете перемещать наборы данных с одной части дерева ZFS на другую, делая набор данных дочерним для его нового родителя. Это может вызвать изменение многих свойств набора данных, поскольку дети наследуют свойства своих родителей. Все свойства, специфичные для данного набора данных не будут изменены.

Здесь мы перемещаем базу данных из под набора данных zroot/var/db к новому родителю, где вы должны установить некоторые свойства для улучшения устойчивости к отказам.

# zfs rename zroot/var/db/mysql zroot/important/mysql
	   

Отметим, что поскольку точка монтирования унаследована, по всей вероятности это изменит точку монтирования набора данных. Добавление флага -u в команду rename приведет к тому, что ZFS не изменит немедленно данную точку монтирования, предоставляя вам время для на перенастройку свойства для намеченного значения. Отметим, что если машина перезапускается, или набор данных размонтируется вручную, он использует свою новую точку монтирования.

Вы можете переименовать снимок, однако вы не можете переместить снимок за пределы его родительского набора данных. Снимки подробно обсуждаются в Главе 7.

  Ликвидация наборов данных

Данный набор данных плох? Утащите его за сарай и удалите его прочь от ваших страданий при помощи zfs(8).

# zfs destroy db/old
	   

Если вы добавите флаг -r, вы рекурсивно уничтожите всех детей (наборы данных, снимки и т.п.) из этого набора данных. Чтобы уничтожить все клонированные наборы данных, пока вы находитесь в них, воспользуйтесь -R. При рекурсивном уничтожении наборов данных будьте предельно осторожны, поскольку вы зачастую можете быть удивлены тем, что собственно, является потомком набора данных.

Вы можете применить флаги -v и -n чтобы увидеть, что в точности произойдет, когда вы уничтожите набор данных. Флаг -v выдает подробные сведения о том, что будет уничтожено, в то время как -n сообщает zfs(8), что выполнение должно производиться вхолостую. Будучи объединены, они показывают что уничтожит команда на самом деле, прежде чем вы нажмете на спусковой крючок.

 Свойства ZFS

Наборы данных ZFS имеют множество установок, называемые свойствами (properties). Хотя некоторые из них вы можете установить только при создании набора данных, большинство из них можно настраивать при работающих наборах данных. ZFS также предоставляет ряд свойств доступных только на чтение, которые снабжают вас такой информацией, как потребляемый набором данных объем пространства, соотношения сжатия или дедупликации, а также время создания набора данных.

Каждый набор данных наследует свои свойства от его родителя, если данное свойство не устанавливается специально для данного набора данных.

  Просмотр свойств

Инструмент zfs(8) может возвращать определенное свойство или все свойства для некоего набора данных. Примените команду zfs get, нужное свойство и, если вы пожелаете, имя набора данных.

# zfs get compression mypool/lamb
NAME         PROPERTY     VALUE  SOURCE
mypool/lamb  compression  lz4    inherited from mypool
	   

Под NAME вы видите запрошенный вами набор данных, а PROPERTY отображает ограниченное вами свойство. VALUE является тем, во что установлено данное свойство.

SOURCE слегка сложнее. Источник по умолчанию означает, что данное свойство установлено на значения ZFS по умолчанию. Локальный источник означает, что кто-то намеренно установил данное свойство для этого набора данных. Временное свойство было установлено при монтировании набора данных и это свойство возвращается к своему обычному значению после размонтирования набора данных. Наследуемое свойство приходит от родительского набора данных, как это обсуждается в разделе "Взаимосвязи родительский/ дочерний" позже в данной главе.

Некоторые свойства не имеют источник, либо потому, что он неуместен, либо он по существу очевиден. Свойство создания, регистрирующее дату и время создания, не имеет источника. Значение получается от системных часов.

Если вы не укажете имя данных, zfs get отобразит свойства для всех наборов данных. Специальное ключевое слово свойств all возвращает все свойства набора данных.

# zfs get all mypool/lamb
NAME         PROPERTY  VALUE                  SOURCE
mypool/lamb  type      filesystem             -
mypool/lamb  creation  Fri Mar 27 20:05 2015  -
mypool/lamb  used      192K                   -
...
	   

Если вы воспользуетесь all и не укажите имя набора данных, вы получите все свойства всех наборов данных. Это очень большой объем информации.

Отображайте несколько свойств разделяя имена свойств запятыми.

# zfs get quota,reservation zroot/home
NAME        PROPERTY     VALUE  SOURCE
zroot/home  quota        none   local
zroot/home  reservation  none   default
	   

Также вы можете просмотреть свойства при помощи zfs list и модификатора -o. Это более удобно, когда вы хотите просмотреть несколько свойств от множества наборов данных. Для отображения имени набора данных используйте специальное свойство name.

# zfs list -o name,quota,reservation
NAME                QUOTA  RESERV
db                   none    none
zroot                none    none
zroot/ROOT           none    none
zroot/ROOT/default   none    none
...
zroot/var/log        100G     20G
	   

Для просмотра в данном формате для набора данных вы также можете добавить имя набора данных.

  Изменение свойств

Изменяйте свойства при помощи команды zfs set. Задайте имя свойства, новую установку и имя набора данных. Вот изменение свойства compression в off.

# zfs set compression=off mypool/lamb/baby
	   

Подтвердите свои изменения посредством zfs get.

# zfs get compression mypool/lamb/baby
NAME              PROPERTY     VALUE  SOURCE
mypool/lamb/baby  compression  off    local
	   

Большинство свойств применяются только к данным, записанным после изменения свойств. Свойство compression сообщает ZFS о сжатии данных до их записи на диск. Мы обсудим сжатие в Главе 6. Отключение сжатия не разуплотнит никакие данные, пока не будут выполнены изменения. Аналогично, разрешение сжатия не сожмет магическим образом уже записанные на диск данные. Чтобы получить преимущества от разрешения сжатия, вы должны переписать каждый файл. Вам лучше создать новый набор данных, скопировав данные посредством zfs send и уничтожив первоначальный набор данных.

  Свойства, доступные только для чтения

ZFS использует доступные только для чтения свойства для предоставления основной информации о наборе данных. Использование дискового пространства отображается как свойство. Вы не можете изменить то, как много данных вы используете путем изменения свойства, которое сообщает "ваш диск наполовину заполнен" (Глава 6 описывает использование дискового пространства ZFS). Вы можете изменять многие доступные только на чтение свойства добавляя данные на диск или удаляя их. Но вы не можете изменять их напрямую.

 Свойства файловой системы

Одним из ключевых инструментов для управления производительностью и поведением традиционных файловых систем являются параметры монтирования. Вы можете смонтировать файловую систему с доступом только на чтение или воспользоваться флагом noexec для запрета выполнения с нее программ. ZFS использует свойства для достижения тех же самых результатов. Вот свойства, для достижения этих привычных целей.

  atime

atime файла отображает когда был осуществлен последний доступ к файлу. Свойство ZFS atime управляет тем отслеживать ли времена доступа к набору данных. Значение по умолчанию, on, обновляет метаданные atime файла при каждом доступе к файлу. Применение atime означает запись на диск каждый раз при его чтении.

Переключение этого свойства в off избавляет от записи на диск при каждом чтении файла и,как результат, значительный выигрыш производительности. Это может путать почтовые программы и другие подобные утилиты, которые полагаются на способность определения последнего чтения файла.

Оставление atime увеличивает размер снимка. При первом доступе к файлу его atime обновляется. Снимок оставляет первоначальное время доступа к файлу, хотя живая файловая система обновила время доступа. Таково поведение по умолчанию.

  exec

Свойство exec определяет, может ли кто-нибудь выполнять двоичные файлы и команды в этой файловой системе. Значение по умолчанию устанавливается в on, что допускает исполнение. Некоторые среды не разрешают пользователям выполнять программы из их персональных или временных каталогов. Установите свойство exec в off чтобы запретить исполнение программ в данной файловой системе.

Однако, свойство exec не препятствует людям выполнять интерпретируемые сценарии. Если пользователь может выполнять /bin/sh, они могут исполнять /bin/sh /home/mydir/script.sh. Именно оболочка является тем, кто в действительности исполняет - пользователь только выбирает инструкции из сценария.

  readonly

Если вы не хотите, чтобы что-то записывалось в этот набор данных, установите свойство readonly в on. Значение по умолчанию, off, позволяет пользователям изменять набор данных в пределах установленных администратором допусков.

  setuid

Многие люди считают setuid программы опасными. (Правильно написанные setuid программы не опасны. Именно поэтому настоящие situid программы опасны.) Хотя некоторые setuid программы должны оставаться setuid, например, passwd(1) и login(1), редко существует необходимость иметь setuid программы в файловых системах наподобие /home или /tmp. Многие системные администраторы запрещают setuid программы везде кроме определенных файловых систем.

Свойство setuid переключает поддержку setuid. Если оно установлено в on, то файловая система поддерживает setuid. Если установлено off, флаг setuid игнорируется.

 Определяемые пользователем свойства

Свойства ZFS прекрасны, но вы не можете получить их в достаточном объеме, так? Ну,начните добавлять собственные. Возможность хранить собственные метаданные совместно с наборами данных позволяет разрабатывать совершенно новые сферы автоматизации. Тот факт,что потомки автоматически наследуют эти свойства делает жизнь еще проще.

Чтобы убедиться, что пользовательские свойства остаются вашими и не вступают в конфликт с пользовательскими свойствами других людей, создайте пространство имен. Большинство людей выделяют префиксом свои пользовательские свойства при помощи организационного идентификатора и точки. Например, специфичные для FreeBSD свойства имеют формат "org.freebsd:propertyname", наподобие org.freebsd:swap. Если проект illumos создаст своё собственное свойство с именем swap, он назовёт его org.illumos:swap. Два значения не будут конфликтовать.

Например, предположим, что Джуд хочет управлять тем, какие наборы данных должны резервироваться посредством свойств наборов данных. Он создает пространство имен com.allanjude. (Когда свойство ZFS носит ваше имя, вы увековечиваетесь своей работой. Будет это хорошо или плохо - зависит от вашей работы.) В пределах данного пространства имен он создает свойство backup_ignore.

# zfs set com.allanjude:backup_ignore=on mypool/lamb
	   

Сценарии резервного копирования Джуда проверяют значение данного свойства. Если оно установлено в true, процесс резервного копирования игнорирует данный набор данных.

 Взаимосвязи родительский/ дочерний

Наборы данных наследуют свои свойства от родительских наборов данных. Когда вы устанавливаете свойство в наборе данных, это свойство применяется к этому набору данных и ко всем его потомкам. Для удобства вы можете выполнить команды zfs(8) на наборах данных и всех их потомках добавляя флаг -r. Вот мы опрашиваем свойство compression на наборе данных и всех его потомках.

# zfs get -r compression mypool/lamb
NAME              PROPERTY     VALUE  SOURCE
mypool/lamb       compression  lz4    inherited from mypool
mypool/lamb/baby  compression  off    local
	   

Взглянем на значения источника. Первый набор данных, mypool/lamb, наследует данное свойство из родительского пула. Во втором наборе данных это свойство имеет отличное значение. Источник является локальным, что означает, что данное свойство было установлено специально для этого набора данных.

Мы можем восстановить первоначальную установку при помощи команды zfs inherit.

# zfs inherit compression mypool/lamb/baby
# zfs get -r compression mypool/lamb
NAME              PROPERTY     VALUE  SOURCE
mypool/lamb       compression  lz4    inherited from mypool
mypool/lamb/baby  compression  lz4    inherited from mypool
	   

Потомок теперь наследует свойство compression от родителя, которое наследуется от старшего предка.

Когда вы изменяете свойства родителя, эти новые свойства распространяются вниз на потомков.

# zfs set compression=gzip-9 mypool/lamb
# zfs get -r compression mypool/lamb
NAME              PROPERTY     VALUE   SOURCE
mypool/lamb       compression  gzip-9  local
mypool/lamb/baby  compression  gzip-9  inherited from mypool/lamb
	   

Я попросил родительский набор данных использовать сжатие gzip-9. Это проникло вниз к потомкам.

  Наследование и переименование

Когда вы перемещаете или переименовываете набор данных таким образом, что он получает нового родителя, свойства родителя автоматически распространяются вниз на потомков. Локально установленные свойства остаются неизменными, однако наследуемые переключаются на значения от нового родителя.

Вот мы создаем новый родительский набор данных и проверяем его свойство compression.

# zfs create mypool/second
# zfs get compress mypool/second
NAME           PROPERTY     VALUE  SOURCE
mypool/second  compression  lz4    inherited from mypool
	   

Наш набор данных baby использует сжатие gzip-9. Он наследует это свойство от mypool/lamb. Теперь давайте переместим baby на место потомка second и посмотрим что произойдет со свойством compression.

# zfs rename mypool/lamb/baby mypool/second/baby
# zfs get -r compression mypool/second
NAME                PROPERTY     VALUE  SOURCE
mypool/second       compression  lz4    inherited from mypool
mypool/second/baby  compression  lz4    inherited from mypool
	   

Дочерний набор данных теперь относится к другому родителю и наследует свои свойства от нового предка. Потомок сохраняет все локальные свойства.

Данные в дочернем наборе данных, однако, слегка перепутаются. Данные, записанные до включения compression являются не сжатыми. Данные, записанные во время,когда набор данных применял сжатие gzip-9 сжаты при помощи gzip-9. Теперь все данные сжимаются при помощи lz4. ZFS сортирует всеэто для вас автоматически, но представлять себе о том как она это делает - голова пойдет кругом.

  Удаление свойств

Когда вы устанавливаете свойство назад в значение по умолчанию, это совсем не очевидно как изменить источник назад в inherit или default, или как переместить пользовательские свойства, раз уж они были установлены.

Чтобы удалить пользовательские свойства, наследуйте их.

# zfs inherit com.allanjude:backup_ignore mypool/lamb
	   

Это работает даже если вы установили свойство на корневой набор данных.

Чтобы установить свойство вего значение по умолчанию в наборе данных и всех его потомках или полностью удалить пользовательские свойства, воспользуйтесь командой zfs inherit в корневом наборе данных пула.

# zfs inherit -r compression mypool
	   

Это противоречит здравому смыслу, но это сбрасывает пользовательские настройки в вашем корневом наборе данных.

 Монтирование файловых систем ZFS

В традиционной файловой системе вы перечисляете все разделы, их типы и место их монтирования в /etc/fstab. Вы даже перечисляете временные монтирования, такие как устройства гибких дисков и CD ROM, просто для удобства. ZFS позволяет вам создавать такое большое число файловых систем, что это быстро возрастает до лишенного практического смысла состояния.

Каждая файловая система имеет свойство mountpoint, которое определяет где она должна монтироваться. Значение mountpoint по умолчанию строится из mountpoint вашего пула. Если пул не имеет точки монтирования, вы должны назначать точку монтирования для каждого набора данных, который вы хотите монтировать.

# zfs get mountpoint zroot/usr/home
NAME            PROPERTY    VALUE      SOURCE
zroot/usr/home  mountpoint  /usr/home  inherited from zroot/usr
	   

Файловая система обычно монтируется в /usr/home. Вы можете переназначить это при монтировании файловой системы вручную.

Ваш пул zroot, используемый для установки FreeBSD по умолчанию, не имеет установки точки монтирования. Если вы создаете новые наборы данных непосредственно под zroot, они не будут иметь точек монтирования. Наборы данных , созданные в zroot, скажем, под /usr унаследуют точку монтирования от своего родительского набора данных.

Любой пул, отличный от пула с корневой файловой системой обычно имеет точку монтирования с именем после этого пула. Если вы создали пул с именем db, он будет смонтирован в /db. Все потомки будут наследовать свои точки монтирования из этого пула, пока вы не измените их.

Когда вы изменяете свойство mountpoint для файловой системы, файловая система и все потомки, которые унаследовали точку монтирования становятся размонтированными. Если новое значение - legacy, то они остаются не монтированными. В противном случае они автоматически монтируются в новом местоположении, если свойство первоначально было legacy или none, или если были смонтированы перед изменением свойства. Кроме того, все совместно используемые файловые системы прекращают быть таковыми и возвращаются к совместному использованию в новом местоположении.

Вточности как и обычные файловые системы, файловые системы ZFS не должны быть обязательно смонтированными. Свойство canmount управляет поведением монтирования файловой системы. Если canmount установлено в значение yes, выполнение zfs mount -a смонтирует файловую систему, в точности как mount -a. Когда вы разрешаете ZFS в /etc/rc.conf, FreeBSD выполняет zfs mount -a при запуске.

Когда свойство canmount установлено в значение noauto, набор данных может быть смонтирован или размонтирован только в явном виде. Набор данных не монтируется автоматически ни при создании или импортировании, а также не монтируется посредством команды zfs mount -a или не демонтируется с помощью zfs unmount -a.

Интересные вещи могут происходить, когда вы устанавливаете canmount в значение off. Вы можете иметь два не смонтированных набора данных с одной и той же точкой монтирования. Набор данных может существовать исключительно в целях того, чтобы быть предком для наборов данных в будущем, но на самом деле не хранить файлы, как мы увидим это ниже.

Дочерние наборы данных не наследуют свойство canmount.

Изменение свойства canmount не выполняет автоматическое монтирование или размонтирование файловой системы. Если вы сделаете запрет на смонтированной или размонтированной файловой системе, вам необходимо размонтировать файловую систему вручную или выполнить перезагрузку.

  Наборы данных без точки монтирования

Наборы данных ZFS имеют иерархию. Вам может понадобиться создать набор данных, который никогда не будет содержать никаких файлов только для того, чтобы он мог быть общим предком для ряда других наборов данных. Рассмотрим установки по умолчанию FreeBSD 10.1 или новее.

# zfs mount
zroot/ROOT/default    /
zroot/tmp             /tmp
zroot/usr/home        /usr/home
zroot/usr/ports       /usr/ports
zroot/usr/src         /usr/src
...
	   

У нас имеются все виды наборов данных под /usr, однако не существует никакого смонтированного набора данных /usr. Что происходит?

zfs list отображает,что набор данных существует, и что он имеет тоску монтирования /usr. Однако давайте проверим наши свойства mountpoint и canmount для zroot/usr и всех его потомков.

# zfs list -o name,canmount,mountpoint -r zroot/usr
NAME           CANMOUNT  MOUNTPOINT
zroot/usr           off  /usr
zroot/usr/home      on   /usr/home
zroot/usr/ports     on   /usr/ports
zroot/usr/src       on   /usr/src
	   

При canmount установленном в off, набор данных zroot/usr никогда не монтируется. Все файлы, записанные в /usr, например, команды в /usr/bin и пакеты в /usr/local попадают в корневую файловую систему. Точки монтирования нижнего уровня, такие как /usr/src, имеют свои собственные наборы данных, которые монтируются.

Набор данных существует только чтобы быть родительским для его дочерних наборов данных. Вы можете увидеть нечто аналогичное в вашем разделе /var.

  Множественные наборы данных с одной и той же точкой монтирования

Установка canmount в значение off позволяет наборам данных использоваться исключительно в качестве механизма наследования свойств. Одна из причин установки canmount в off заключается в наличии двух наборов данных с одной и той же точкой монтирования, с тем, чтобы потомки обоих наборов данных появлялись в одном и том же каталоге, но имели бы различные наследуемые свойства.

Установщик FreeBSD не имеет mountpoint в пуле по умолчанию, zroot. Когда вы создаете новый набор данных, вы должны назначить точку монтирования для него.

Если вы не хотите назначать точку монтирования для каждого создаваемого вами непосредственно в пуле набора данных, можете назначить mountpoint для / на пул zroot и оставить установку canmount в off. Таким образом вы можете создать новый набор данных, причем он должен наследовать mountpoint. Это очень простой пример применения множества наборов данных с одной и той же точкой монтирования.

Представим, что вам нужен каталог /opt с двумя наборами подкаталогов. Некоторые из этих подкаталогов содержат программы и никогда не должны перезаписываться после их установки. Другие каталоги содержат данные. Вы должны ограничить функциональность возможности выполнения программ только на уровне файловой системы.

# zfs create db/programs
# zfs create db/data
	   

Теперь дадим этим двум наборам данных нашу mountpoint в /opt и сообщим им, что они не могут монтироваться.

# zfs set canmount=off db/programs
# zfs set mountpoint=/opt db/programs
	   

Установим ваши программы в этот набор данных и затем сделаем его доступным только для чтения.

# zfs set readonly=on db/programs
	   

Вы не можете запускать программы из набора данных db/data, поэтому выключим exec и setuid. Тем не менее, нам нужно записывать данные в эти каталоги.

# zfs set canmount=off db/data
# zfs set mountpoint=/opt db/data
# zfs set setuid=off db/data
# zfs set exec=off db/data
	   

Теперь создадим дочерние наборы данных. Потомок набора данных db/programs унаследует эти свойства набора данных, в то время как потомки набора данных db/data унаследуют другой набор свойств.

# zfs create db/programs/bin
# zfs create db/programs/sbin
# zfs create db/data/test
# zfs create db/data/production
	   

Теперь у нас есть четыре набора данных, смонтированных внутри /opt, два для бинарных {исполняемых} и два для данных. Насколько известно пользователям, это обычные каталоги. Независимо от того, что говорят разрешения файлов, тем не менее, никто не сможет писать в два из этих каталогов. Вне зависимости от того, что будут пихать туда злые люди, система не сможет распознавать исполняемые файлы и файлы с назначением индентификатора на время исполнения (setuid) в двух других. Когда вам нужны другие наборы данных для данных или программ, создавайте их как потомков наборов данных с нужными вам свойствами. Изменение свойств родительских наборов данных немедленно распространяется на всех потомков.

  Пулы без точки монтирования

Хотя обычно пул монтируется в каталог с именем после этого пула, это не обязательно должно быть так.

# zfs set mountpoint=none mypool
	   

Данный пул больше не монтируется. Никакие наборы данных в пуле не доступны, пока вы не зададите точку монтирования. Ровно так установщик FreeBSD создает пул для операционной системы.

# zfs set mountpoint=/someplace mypool/lamb
	   

Каталог будет создан, если необходимо, и файловая система смонтируется.

  Монтирование и демонтирование файловых систем вручную

Чтобы смонтировать файловую систему вручную, воспользуйтесь zfs mount и именем нужного набора данных. Это наиболее обычное применение для файловой системы с canmount установленным в noauto.

# zfs mount mypool/usr/src
	   

Для размонтирования файловой системы и всех ее потомков применяйте zfs unmount.

# zfs unmount mypool/second
	   

Если вы хотите временно смонтировать набор данных в другом местоположении, воспользуйтесь флагом -o для определения новой точки монтирования. Эта точка монтирования сохранится только пока вы не размонтируете этот набор данных.

# zfs mount -o mountpoint=/mnt mypool/lamb
	   

Вы можете монтировать набор данных только если он имеет определенную mountpoint. Определение временной точки монтирования при не заданной точке монтирования вернет вам ошибку.

 ZFS и /etc/fstab

Если вам нравится, вы можете выбрать управление некоторыми или даже всеми точками монтирования вашей файловой системы ZFS при помощи /etc/fstab. Установите свойство mountpoint в legacy. Это размонтирует вашу файловую систему.

# zfs set mountpoint=legacy mypool/second
	   

Теперь вы можете смонтировать этот набор данных при помощи команды mount(8):

# mount -t zfs mypool/second /tmp/second
	   

Вы также можете добавить наборы данных ZFS в /etc/fstab вашей системы. Используйте полное имя набора данных в качестве файлов устройств (device node). Установите тип в zfs. Вы можете использовать стандартные параметры файловой системы noatime, noexec, readonly или ro и nosuid. (Вы также можете в явном виде задать поведение по умолчанию для atime, exec, rw и suid, но они являются определениями ZFS по умолчанию.) Порядок монтирования обычный, однако поле fsck игнорируется. Вот запись /etc/fstab, которая монтирует набор данных scratch/junk nosuid в /tmp.

scratch/junk /tmp nosuid 2 0
	   

Однако, мы рекомендуем применять свойства ZFS для управления вашими монтированиями. Свойства могут делать почти все, что делает /etc/fstab и даже больше.

 Тонкая настройка томов ZFS

Zvol достаточно просты - вот кусок пространства в виде блочного устройства, используйте его. Вы можете настроить как том использует пространство и какой вид файлов устройств (devce node)

  Резервирование пространства

Свойство volsize zvol определяет логический размер тома. По умолчанию создание тома резервирует объем пространства для набора данных, равное размеру тома. (Если вы заглянете вперед в Главу 6, оно устанавливает refreservation равного размера.) Изменение volsize изменяет выделение. volsize может быть установлен только кратным свойству volblocksize и не может быть нулем.

Без резервирования том может работать за пределами пространства, что приведет в результате к неопределенному поведению или разрушению данных, в зависимости от того, как используется том. Подобные результаты могут получиться также когда размер тома изменяется при его использовании, в особенности при усечении размера. Корректировка размера тома может запутать приложения, использующие блочное устройство.

Zvols также поддерживает разреженные тома (sparse volumes), также называемые динамическим выделением (thin provisioning). Разреженные тома, это тома в которых резервируется объем меньше размера тома. По сути, разреженный том позволяет выделять больше пространства, чем доступно в наборе данных. При помощи разреженных томов вы можете, скажем, создать десять разреженных томов по 1ТБ в вашем наборе данных 5ТБ. Пока ваши тома не используются в режиме сильного заполнения, никто не заметит что вы вышли за пределы допустимого.

Разреженные тома не рекомендуются. Запись в разреженный том может завершиться отказом "out of space", даже если ваш том сам по себе выглядит только частично заполненным.

Определение разреженного тома во время создания задается параметром -s в команде zfs create -V.

  Режим Zvol

FreeBSD обычно выдает zvol для операционной системы как поставщиков geom(4), предоставляя им максимальную гибкость. Вы можете изменить это при помощи свойства volmode.

Установка volmode тома в dev выдает тома только как символьные устройства в /dev. Доступ к таким томам может быть осуществлен только как к сырым файлам дисковых устройств. Они не могут разбиваться на разделы или монтироваться, а также они не могут принимать участие в RAID или других функциональностях GEOM. Они быстрее. В некоторых случаях, когда вы не доверяете устройству, использующему том, режим dev может быть безопаснее.

Установка volmode в none означает, что том не выдается за пределы ZFS. Такие тома, однако, могут выдавать снимки, быть клонированными и реплицироваться. Эти тома могут быть удобными для целей резервного копирования.

Установка volmode в default означает, что выдача тома управляется вашим sctl vfs.zfs.vol.mode. Вы можете установить режим zvol по умолчанию по всей системе. Значение 1 означает, что значение по умолчанию это geom, 2 означает dev, а 3 означает none.

Когда вы изменяете свойство на томе, находящемся в работе, это не имеет результата. Это свойство обрабатывается только при создании тома и импорте пула. Вы можете повторно создать устройство zvol путем переименования тома с помощью zfs rename.

 Целостность наборов данных

Основная защита ZFS работает на уровне VDEV. Это именно то место, где блоки и диски становятся плохими в конце концов. Некоторые аппаратные пределы, однако, ограничивают резервирование пула. Очень мало портативных компьютеров имеют достаточное число жестких дисков для применения зеркалирования, не говоря уж об RAID-Z.Однако вы можете кое-что сделать на уровне данных для предоставления некоторой избыточности путем применения контрольных сумм, избыточности метаданных и копий. Большинство пользователей никогда не должны касаться первых двух, а пользователи с избыточными виртуальными устройствами, вероятно, хотят оставить исключительно все три.

  Контрольные суммы

ZFS вычисляет и сохраняет контрольные суммы для каждого записываемого ею блока. Это гарантирует,что когда блок считывается обратно, ZFS может удостовериться, что он тот же, что были при записи, а не был втихую испорчен тем или иным способом. Свойство checksum управляет какой алгоритм контрольных сумм использует набор данных. Разрешенными установками являются on, fletcher2, fletcher4, sha256, off и noparity.

Значение по умолчанию, on, использует алгоритм, выбранный разработчиком OpenZFS. В 2015 году таким алгоритмом был fletcher4, однако в последующих выпусках могут быть изменения.

Стандартный алгоритм, fletcher4, является алгоритмом контрольных сумм по умолчанию. Он достаточно хорош для большинства применений и очень быстрый. Если вы хотите применять fletcher4 повсюду и всегда, вы можете установить данное свойство в fletcher4. Однако, мы рекомендуем оставить значение по умолчанию в on и позволить ZFS обновить алгоритм контрольных сумм вашего пула, когда придет его время.

Значение off запрещает проверку целостности данных пользователя.

Значение noparity не только запрещает проверку целостности данных, но также запрещает сопровождение контрольных сумм для пользовательских данных. Эта установка используется внутренне для устройства дампа, расположенного в пуле RAID-Z и не должна применяться ни в каких других наборах данных. Запрещение контрольных сумм не рекомендуется.

Старые версии ZFS применяли алгоритм fletcher2. Хотя он и поддерживается для более старых пулов, он, несомненно, не поощряется.

Алгоритм sha256 медленнее чем fletcher4, однако вероятность противоречий меньше. В большинстве случаев противоречия не вредоносные. Алгоритм sha256 часто рекомендуется при выполнении дедупликации.

  Копии

ZFS хранит две или три копии важных метаданных и может предоставить такие же средства для важных данных пользователя. Свойство copies сообщает ZFS сколько сохранять копий пользовательских данных. ZFS пытается разместить эти копии на разных дисках или, если это возможно, размещать их так далеко на физическом диске, как это возможно, чтобы помочь защититься от аппаратных сбоев. Когда вы увеличиваете свойство copies, ZFS также увеличивает число копий метаданных для набора данных, до максимального значения три.

Если ваш пул работает на двух зеркалированных дисках и установите значение copies в 3, вы будете иметь шесть копий ваших данных. Одна из них должна пережить свое опрометчивое применение dd(1) на сыром устройстве поставщика или подобный прыжок с крыши.

Увеличение или уменьшение числа копий оказывает воздействие только на данные, записываемые после такого изменения установок. Изменение copies с 1 до 2,несомненно, не создаст дублирующие копии всех ваших данных, как мы видим здесь. Создайте файл с 10МБ случайных данных:

# dd if=/dev/random of=/lamb/random1 bs=1m count=10
10+0 records in
10+0 records out
10485760 bytes transferred in 0.144787 secs (72421935 bytes/sec)
# zfs set copies=2 mypool/lamb
	   

Теперь каждый блок сохранен дважды. Если одна из копий будет разрушена, ZFS будет все еще в состоянии читать ваш файл. Он будет знать какой из блоков конкретно разрушен, поскольку он не будет соответствовать своей контрольной сумме. Однако взглянем на пространство, потребляемое нашим пулом (пространство REFER в списке пула).

# zfs list mypool/lamb
NAME         USED   AVAIL  REFER  MOUNTPOINT
mypool/lamb  10.2M  13.7G  10.1M  /lamb
	   

Используются только 10МБ, которые мы записали. Никакая дополнительная копия для этого файла не была создана, поскольку мы записали его до изменения свойства copies.

При copies установленных в 2, однако, если мы запишем другой файл или повторно запишем первоначальный файл, мы увидим другое использование диска.

# dd if=/dev/random of=/lamb/random2 bs=1m count=10
10+0 records in
10+0 records out
10485760 bytes transferred in 0.141795 secs (73950181 bytes/sec)
	   

Взглянем на использование диска теперь.

# zfs list mypool/lamb
NAME         USED   AVAIL  REFER  MOUNTPOINT
mypool/lamb  30.2M  13.7G  30.1M  /lamb
	   

Общий объем используемого пространства 30МБ, 10 для первого файла случайных данных и 20 для 2 копий второго файла 10МБ.

Когда мы посмотрим на файлы с помощью ls(1), она отобразит только реальный размер:

# ls -l /lamb/random*
-rw-r--r-- 1 root wheel 10485760 Apr 6 15:27 /lamb/random1
-rw-r--r-- 1 root wheel 10485760 Apr 6 15:29 /lamb/random2
	   

Если вы хотите действительно унавозить устойчивость вашего набора данных,

  Избыточность метаданных, рассмотрите избыточность метаданных.

Каждый набор данных хранит свою внутреннюю копию метаданных, так что если какой-то отдельный блок поврежден, объем утраченных пользовательских данных ограничен. Такая дополнительная копия является добавлением к любой избыточности предоставленной на уровне VDEV (например, посредством зеркалирования или RAID-Z). Она также добавляется ко всем другим дополнительным копиям, определяемым свойством copies (ниже), до трех копий в сумме.

Свойство redundant_metadata позволяет вам решить насколько избыточными вы хотите сделать свои метаданные. Большинство пользователей никогда не должно изменять это свойство.

Когда redundant_metadata установлено в all (значение по умолчанию), ZFS хранит дополнительную копию всех метаданных. Если один блок на диске разрушен, в худшем случае будет утрачен один блок пользовательских данных.

Когда redundant_metadata установлен в most, ZFS хранит дополнительную копию только большинства метаданных. Это может повысить производительность операций случайных записей, поскольку должно записываться меньше метаданных. Когда только большинство метаданных является избыточными, в худшем случае примерно 100 блоков пользовательских данных может быть утрачено при разрушении отдельного блока данных. Точное поведение того, какие блоки метаданных хранятся избыточно может изменяться в последующих выпусках.

Если вы установили redundant_metadata в most и copies в значение 3, а данные обитают в зеркалированном пуле, то ZFS сохраняет 6 копий большинства метаданных и по четыре копии данных и остальных метаданных.

Данное свойство было разработано для конкретных случаев применения, которые часто обновляют метаданные, например, для баз данных. Если данные уже защищены достаточно сильной отказоустойчивостью, уменьшение числа копий метаданных, которые должны быть записаны при каждом изменении базы данных, может улучшить производительность. Изменяйте это значение только если вы знаете что делаете.

Теперь у вас есть контроль над наборами данных, давайте поговорим о сопровождении пула.