ZFS в Linux

В Linux есть две реализации ZFS. Одна из них — модуль FUSE, но мы воспользуемся настоящим модулем ядра из проекта «ZFS в Linux» (http://zfsonlinux.org). ZFS доступна для многих дистрибутивов, но лучше всего поддерживается в Ubuntu и Gentoo — часто ли вы слышите, что их упоминают вместе? Есть и некоторые системные требования — в частности, ZFS надежно работает только на 64-битных ядрах из-за активного использования виртуальной памяти. Ей также нужно много оперативной памяти, и она не слишком хорошо работает в системах с ограниченным объемом ОЗУ: минимальное, с которым я ею пользовался — 2 ГБ. Для установки ZFS в Ubuntu и ее производных нужно добавить PPA zfs-native (ppa:zfs-native/stable) к списку источников и установить пакет ubuntu-zfs. Пользователям Gentoo достаточно скомандовать emerge zfs.

Так как ZFS использует модули ядра, не включенные в само ядро, то при каждой перекомпиляции или обновлении ядра придется пересобирать модули ZFS, иначе она не будет работать. Это та же проблема, что и с драйверами видеокарт Nvidia и другими подобными вещами. Если у вас дистрибутив, использующий DKMS, например, Ubuntu, все произойдет автоматически: при установке нового ядра в составе нормального обновления модули будут пересобраны, a initramfs — обновлена. При установке ZFS из исходников не забудьте собрать их до загрузки нового ядра.

Пакет ZFS устанавливает с десяток команд, но обычно используются только две из них; остальные — проверочные и отладочные утилиты. Сравните их с полусотней команд, которые устанавливает LVM, и вы поймете, что здесь все проще. Те самые две команды — zpool и zfs. Первая управляет пулами ZFS, группами файловых систем на одном и том же устройстве(ах), нечто вроде сочетания физических томов и групп томов LVM. Вторая управляет самими файловыми системами. Обеим командам нужны права суперпользователя-root, а если вы вошли от имени обычного пользователя, предваряйте каждую команду префиксом sudo. Приступим к делу и создадим пул на /dev/sdb: zpool create firstpool sdb1

Синтаксис команды прост: первый аргумент — имя пула, второй — имя используемого устройства. В названиях дисковых устройств не обязательно указывать начальное /dev/, но если вы хотите воспользоваться файлами для тестирования, следует указать полный путь. Для обращения к различными типам устройств, пригодных для создания пула, в ZFS используется термин “vdev (виртуальное устройство)”. Наряду с именами устройств и путями также можно пользоваться идентификаторами дисков, перечисленными в /dev/disk/by-id. Чтобы увидеть результат, выполните команду

% zpool list

NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT firstpool 1.98G 102K 1.98G 0% 1.00x ONLINE -

Мы не только создали свой первый пул, но в нем уже есть смонтированная файловая система, и нам не нужно запускать команды mkfs * или mount.

% df -Th /firstpool

Filesystem Type Size Used Avail Use% Mounted on firstpool zfs 2.0G 0 2.0G 0% /firstpool

Теперь можно скопировать файлы в /firstpool, как в любую другую файловую систему. Но иметь одну большую файловую систему, как и хранить все в корневом каталоге, не очень удобно. В ZFS можно создать тома ZFS внутри этого пула таким образом: zfs create firstpool/testdir

Эта бравая команда — одна — создает том, помещает в него файловую систему и монтирует ее. Теперь скопируйте несколько файлов в /firstpool/testdir и выполните команду

% zfs list

NAME USED AVAIL REFER MOUNTPOINT firstpool 952M 1.02G 31K/firstpool firstpool/testdir 952M 1.02G 952M /firstpool/testdir

Обратите внимание, что пул и файловая система testdir занимают одинаковый объем, потому что файловая система у нас всего одна.

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

Пока все хорошо, но автоматически монтировать тома в соответствии с их именами не всегда удобно. Если вы захотите иметь раздел /home на томе ZFS, он будет не в том месте. Наряду с данными, у файловых систем ZFS есть свойства, для просмотра которых используется команда zfs get: zfs get all firstpool/testdir

Вы увидите множество свойств, управляющих всеми аспектами поведения файловой системы, но сейчас нас интересует свойство “mountpoint [точка монтирования]”. Его и большинство других свойств можно изменить командой zfs set: zfs set mountpoint=/home/test firstpool/testdir

Теперь при монтировании этого тома ZFS смонтирует его в новую точку. Все тома ZFS по умолчанию монтируются командой zfs mount -а, которая обычно запускается загрузочными скриптами. Чтобы том не монтировался автоматически, нужно установить параметр “canmount” в “noauto”, в этом случае том придется монтировать вручную командой zfs mount firstpool/testdir

В отличие от стандартной команды mount, в ZFS не требуется, чтобы точка монтирования уже существовала, но если она существует, то должна быть пустой. Также можно установить “mountpoint” в “legacy” и управлять монтированием с помощью /etc/fstab обычным образом.

Есть и другие свойства, достойные изучения. Например, для установки квоты файловой системы достаточно выполнить команду zfs set quota=10G firstpool/testdir

Свойства также можно задавать при создании файловой системы. Кроме того, свойства, которые не заданы явно, наследуются от родителя. Предположим, что вы создаете файловую систему для /home командой zfs create firstpool/home -о mountpoint=/home -о quota=10G

Тогда каждая пользовательская файловая система, точка монтирования которой находится внутри /home, тоже получит квоту в 10 ГБ, если создавать ее командой zfs create /firstpool/home/user

Вот так просто можно создавать файловые системы для отдельных пользователей с квотами, не создавая разделов и логических томов, не запуская mkfs и не редактируя /etc/fstab. А когда файловая система больше не нужна, вы избавляетесь от нее и возвращаете все используемое ею пространство командой zfs destroy. ZFS предполагает, что вы знаете, что делаете. Она удалит данные тихо и без лишних вопросов. Если вы не уверены, сначала вызовите ее с ключами -v и -n (подробный вывод и пробный запуск без реальных изменений в системе).

zfs destroy -vn firstpool/home/user

При задании квоты файловой системы вы задаете только максимально возможный размер пространства — его доступность не гарантируется. Вышедший из-под контроля процесс по-прежнему сможет захватить все место в одной файловой системе, не оставив ничего другим. ZFS борется с этим с помощью свойства reservation [резервный объем] файловой системы. Это свойство выделяет указанный объем для данной файловой системы. У файловой системы может быть либо квота, либо резервный объем, либо и то, и другое. И квоту, и резервный объем можно изменять по желанию, если количество свободного места такое позволяет. Не нужно беспокоиться об изменении размеров томов или файловых систем — просто измените свойство на любое желаемое значение. Если для какого-то каталога или пользователя нужно больше пространства, увеличьте его. Когда место больше не нужно, снова уменьшите квоту.

RAID

Мы создали свой первый пул, используя одно устройство, но zpool можно создать с любым количеством устройств в разных сочетаниях, с него пошел первый заработок в Интернете. Устройства могут быть либо разделами, либо целыми дисками; в ZFS даже не нужно разбивать диски на разделы. Конечно, диск, содержащий файловую систему /boot или корневую файловую систему, разбивать на разделы придется, но чистому диску с данными разделы ни к чему, zpool create poolname sda sdb

Эта команда создает пул, охватывающий два диска. Это аналогично нескольким устройствам в группе томов LVM или RAID О (который на самом деле вовсе не RAID). Размер пула — сумма размеров включенных в него устройств. Также есть возможность создать настоящие RAID-массивы: zpool create poolname mirror sda sdb zpool create poolname raidz sda sdb sdc

Первая команда создает эквивалент массива RAID 1, а вторая — ZFS-версию RAID 5 без падения производительности на записи, характерного для обычного RAID 5.

Снимок — копия файловой системы (доступная только для чтения) на момент создания снимка. Такую копию можно сделать перед внесением рискованных изменений, чтобы откатиться к ней на случай краха, или хранить ее как резервную копию системы, защищенную от вмешательства пользователей, если не от неисправностей диска. Снимки также позволяют сделать резервную копию данных, которые могут меняться во время резервного копирования, например, содержимого /var. Можно сделать снимок файловой системы с резервной копией снимка, зная, что он не изменится. Для создания снимка используется команда zfs snapshot mypool/myvolume@snapshotname

Имя снимка, указываемое после @, может быть любым. При создании снимка тот не занимает места на диске. При добавлении или изменении файлов после создания снимка свободного места на диске станет меньше, так как файловой системе приходится хранить старые и новые копии. Снимки находятся в скрытом каталоге .zfs. Снимок, созданный выше, если вы не меняли точку монтирования, можно найти в /mypool/myvolume/.zfs/ snapshot/snapshotname. Каталог .zfs является по-настоящему скрытым, а не просто имеет точку в начале имени: он не будет виден, даже если включить отображение скрытых файлов или попытаться просмотреть его командой Is -а. Чтобы его увидеть, нужно изменить свойство “snapdir” файловой системы или пула с “hidden” на “visible”.

Когда снимок больше не нужен, можно удалить его и освободить все используемое им место командой zfs destroy mypool/myvolume@snapshotname

Чтобы удалить диапазон снимков, можете воспользоваться символом %: zfs destroy mypool/myvolume@snapshot1%snapshot5 zfs destroy mypool/myvolume@%snapshot5

Первая команда удаляет все снимки с 1 по 5 включительно, вторая удаляет все снимки начиная с пятого и старше. Диапазоны формируются не по именам, а по датам снимков, поэтому при запуске команды zfs destroy mypool/myvolume@%thursday будет удален и снимок, сделанный в среду. Список всех снимков можно вывести командой zfs list: zfs list zfs list -t snapshot zfs list -t all zfs list -t all -r firstpool/testdir

Первая команда перечисляет только файловые системы, вторая — только снимки, третья и то, и другое, а последняя команда перечисляет только то, что принадлежит указанной файловой системе.

Существует программа, которая автоматически делает снимки через регулярные интервалы и удаляет старые снимки. Она называется zfs-autosnapshot. Это скрипт оболочки и набор заданий Cron, которые можно скачать с сайта https://aithub.com/zfsonlinux/ zfs-autosnapshot или из РРА Ubuntu. При автоматическом создании снимков часто меняющихся файловых систем может расходоваться много места на диске, поэтому некоторые системы стоит исключить из создания снимков, установив параметр сот. sun:autosnapshot в false. Если вы хотите откатить систему к какому-либо снимку, это можно сделать с параметром rollback: zfs rollback mypool/myvolume@snapshotname

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

zfs clone firstpool/mydata@today firstpool/today

Как и снимок, клон сначала не занимает места на диске, но на­чинает съедать его, если либо исходная файловая система, либо клон изменяются. Снимок клону необходим — нельзя удалить снимок, если сначала не удалить клон. Теперь можно записывать данные в каталоги firstpool/today и firstpool/mydata отдельно друг от друга.