Глава 7. Моментальные снимки и клоны

Содержание

7. Снимки и клоны
Копирование при записи
Как работает снимок
Применение снимков
Создание снимка
Изменения набора данных и пространство снимка
Рекурсивные снимки
Расширенный набор данных и просмотр снимка
Просмотр наборов данных по типу
Изменение списка вывода zfs
Вывод списков снимков по умолчанию
Сценарии и ZFS
Использование пространства на снимок
Доступ к снимкам
Скрытый Snapdir
Монтирование снимков
Удаление снимков
Выполнения уничтожения вхолостую
Рекурсия и диапазоны
Откат
Нахождение разницы снимков
Автоматический режим снимка
Циклическое расписание
Инструменты ZFS
zfs-auto-snapshot
Разрешение автоматического снимка
Просмотр автоматического снимка
Получение остроумных вариантов при помощи zfs-auto-snap
Захваты
Закладки
Клоны
Создание клона
Просмотр клонов
Удаление клонов и снимков
Продвижение клонов
Безопасное управление клонами, снимками и рекурсией

Одной из самых мощных функциональностей ZFS являются снимки. Снимок файловой системаы или zvol позволяет получить доступ к копии набора данных, как будто бы она существовала в определенный момент. Снимки доступны только для чтения, и никогда не изменяются. Снимок является замороженным образом ваших файлов, к которым вы можете получить доступ на досуге. В то время как резервное копирование, как правило, фиксирует систему на протяжении минут или часов, выполнение резервного копирования снимке означает, что резервная копия получает один последовательный образ системы, устраняя сообщения типа: tar: file changed as we read it и их двоюродных собратьев.

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

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

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

Лучше всего, что внутренне присущее ZFS копирования-при-записи (COW, copy-on-write) означает, что снимки "бесплатны". Создание снимка мгновенно и не требует дополнительного пространства.

 Копирование при записи

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

ZFS никогда не перезаписывает существующие блоки файла. Когда нечто изменяет файл, ZFS определяет блоки подлежащие изменению и записывает их в новое местоположение на диске. Это называется копированием-при-записи, или COW (copy-on-write). Старые блоки остаются нетронутыми. Обрезанная запись может потерять самые новые изменения в вашем файле, однако предыдущая версия вашего файла все ещё остаётся нетронутой.

Невозможность утраты файла является великим преимуществом копирования-при-ззаписи, однако COW открывает и ряд других возможностей. ZFS создает снимки с помощью отслеживания старых версий измененных блоков. Это звучит обманчиво просто, не так ли? Да,так. Но, как и во всем простом, черт кроется в деталях. Мы обсуждали то, как данные ZFS хранит данные в Главе 3., но давайте углубимся.

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

Каждый диск в пуле содержит четыре копии меток своей ZFS: две в начале диска и две в конце. {Прим. пер.: каждая метка является 256кБ блоком - см. 10.3. Структура ZFS в нашем переводе Главы 10. ZFS: Зеттабайт файловая система 2й редакции книги Маршала Кирка МакКузика, Джорджа В. Невил-Нейла и Роберта Н.М. Ватсона "Архитектура и реализация операционной системы FreeBSD" (ISBN-13: 978-0-321-96897-5).} Каждая метка содержит имя пула, глобальный уникальный идентификатор, GUID (Globally Unique ID) и информацию по каждому участнику VDEV. Каждая метка также содержит 128кБ для уберблоков.

Каждый уберблок является объектом фиксированного размера, который содержит указатель на набор мета объекта, MOS (Meta Object Set). номер группы транзакций, которая создала уберблок и контрольную сумму.

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

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

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

Уберблок является корнем всего дерева. Все исходит из него. ZFS не может изменить уберблок не прерывая правила копирования-при-записи, следовательно она замещает уберблоки по кругу. Каждая метка выделяет 128кБ для уберблоков. Диски с 512-байтовыми секторами имеют 128 уберблоков {Прим. пер.: так по тексту, на самом деле 256?}, в то время как диски с 4кБ секторами имеют 32 уберблока. Если у вас есть диск с 16кБ секторами, он будет иметь только восемь уберблоков. Каждое обновление файловой системы добавляет новый уберблок в этот массив. Когда массив заполняется, перезаписывается самый старший уберблок.

Когда система стартует, ZFS сканирует все свои уберблоки, находит самый новый из них с верной контрольной суммой и применяет его для импорта вашего пула. Даже если самое последнее обновление каким-то образом было испорчено, система может импортировать непротиворечивую версию того, каким пул был за несколько секунд до этого. Если система отказала при записи, самые последние данные оказываются потерянными - но эти данные все равно так и не попали бы на диск. Они утрачены, ZFS не может помочь вам. Применение копирования-при-записи означает, что ZFS не страдает от проблем, которые делают fsck(8) необходимым для традиционных файловых систем.

 Как работает снимок

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

Снимкам также требуется новая порция метаданных ZFS, а именно список неиспользуемых (dead list). Список неиспользуемых набора данных записывает все блоки набора данных, которые использовались самым последним снимком, но больше не являются частью этого набора данных. Когда вы удаляете файл из набора данных, используемые этим файлом блоки добавляются в список неиспользуемых этого набора данных. Когда вы создаете снимок, список неиспользуемых активного набора данных передается создаваемому снимку, а активный набор данных получает новый, пустой список неиспользуемых.

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

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

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

Это означает, что ZFS не сохраняет копии всех версий каждого файла. Когда вы создаете новый файл и удаляете его до взятия снимка, файл исчезает. Каждый снимок содержит копии всех файлов, если они присутствовали на момент создания снимка. ZFS не сохраняет историю подобно HAMMER-у DragonFly.

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

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

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

 Применение снимков

Чтобы поэкспериментировать со снимками, давайте создадим новый набор данных файловой системы и наполним его некоторыми файлами.

# zfs create -o mountpoint=/sheep mypool/sheep
# cd /sheep
# dd if=/dev/random of=randomfile bs=1m count=1
# fetch -o zfsbook.html http://www.zfsbook.com/
# date > date.txt
	   

Это предоставит нам некоторые данные для манипуляций с ними.

  Создание снимка

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

# zfs snapshot mypool/sheep@snap1
	   

Просматривайте снимки посредством zfs list -t snapshot. Чтобы просмотреть снимки определенного набора данных добавьте флаг -r и имя набора данных.

# zfs list -t snapshot -r mypool/sheep
NAME                USED  AVAIL  REFER  MOUNTPOINT
mypool/sheep@snap1     0      -  1.11M  -
	   

Отметим, что используемый снимком объем пространства (колонка USED) равен 0. Каждый блок снимка все еще используется активным набором данных, следовательно снимки не используют дополнительное пространство.

  Изменения набора данных и пространство снимка

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

# dd if=/dev/random of=randomfile bs=1m count=1 oseek=1
# date > date.txt
	   

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

# zfs list -t snapshot -r mypool/sheep
NAME                USED  AVAIL  REFER  MOUNTPOINT
mypool/sheep@snap1   72K      -  1.11M  -
	   

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

Теперь давайте создадим второй снимок и посмотрим сколько пространства использует он.

# zfs snapshot mypool/sheep@second
# zfs list -t snapshot -r mypool/sheep
NAME                 USED  AVAIL  REFER  MOUNTPOINT
mypool/sheep@snap1    72K      -  1.11M  -
mypool/sheep@second     0      -  2.11M  -
	   

Колонка REFER показывает, что первый снимок предоставляет вам доступ к 1.11МБ данных, в то время как второй позволяет вам видеть 2.11МБ данных. Первый снимок использует 72кБ пространства, в то время как второй не потребляет ничего совсем. Второй снимок все еще идентичен активным данным.

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

# dd if=/dev/random of=randomfile bs=1m count=1 oseek=1
# zfs list -t snapshot -r mypool/sheep
NAME                  USED  AVAIL  REFER  MOUNTPOINT
mypool/sheep@snap1     72K      -  1.11M  -
mypool/sheep@second  1.07M      -  2.11M  -
	   

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

  Рекурсивные снимки

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

Вот мы создаем снимок загрузочного пула при помощи одной команды.

# zfs list -t snapshot
NAME                              USED  AVAIL  REFER  MOUNTPOINT
zroot@beforeupgrade                  0      -   144K  -
zroot/ROOT@beforeupgrade             0      -   144K  -
zroot/ROOT/default@beforeupgrade     0      -  1.35G  -
zroot/usr@beforeupgrade              0      -   454M  -
zroot/usr/local@beforeupgrade        0      -  1.54G  -
...
	   

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

# dd if=/dev/random of=randomfile bs=1m count=1 oseek=1
# date > date.txt
	   

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

 Расширенный набор данных и просмотр снимка

После того, как вы привыкните к ZFS, вы обнаружите, что вы создали много наборов данных и что каждый набор имеет массу снимков. Попытка найти именно тот снимок,который нужен вам, становится хлопотной. Хотя вы всегда можете опереться на grep(1), инструменты командной строки ZFS имеют очень мощные средства для просмотра и управления вашими снимками и наборами данных. Сочетание альтернативных вариантов позволяет сосредоточиться на том что вы хотите увидеть. Мы начали со zfs list в Главе 4, но давайте теперь решительно пройдем весь путь.

Многие из этих параметров работают помимо снимков и с другими типами наборов данных. Если вы выстраиваете стеки файловых систем вглубь до 19 уровней, вы, скорее всего, захотите ограничивать то что вы видите. Однако, для большинства из нас именно со снимков начинается реальная польза от этих параметров. Большая часть функциональности также работает с zpool(8) и пулами, хотя пулы и не становятся такими сложными как наборы данных.

Простой zfs list отображает нобоы данных файловой системы и zvol, но никаких снимков.

# zfs list
NAME                 USED  AVAIL  REFER  MOUNTPOINT
mypool              4.62G  13.7G    96K  none
mypool/ROOT          469M  13.7G    96K  none
mypool/ROOT/default  469M  13.7G   469M  /
mypool/avolume      4.13G  17.8G    64K  -
...
	   

При помощи имени вы можете рассмотреть отдельный набор данных.

# zfs list mypool/sheep
NAME           USED  AVAIL  REFER  MOUNTPOINT
mypool/sheep  2.11M  13.7G  2.11M  /mypool/sheep
	   

Чтобы просматривать пул или набор данных и всех их потомков используйте флаг -r и имя пула или набора данных.

# zfs list -r mypool/var
NAME              USED  AVAIL  REFER  MOUNTPOINT
mypool/var       22.6G  854G   1.70G  /var
mypool/var/crash  355M  854G    355M  /var/crash
mypool/var/db     224M  854G    187M  /var/db
	   

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

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

Чтобы просматривать наборы данных только определенного типа, воспользуйтесь флаом -t и типом набора данных. Вы можете просматривать файловые системы, тома, снимки и закладки.

# zfs list -t snapshot -r mypool
NAME                   USED  AVAIL  REFER  MOUNTPOINT
mypool@all                0      -    96K  -
mypool/ROOT@all           0      -    96K  -
mypool/ROOT/default@all 84K      -   419M  -
mypool/avolume@all        0      -    64K  -
...
	   

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

# zfs list -t snapshot mypool/sheep@all
NAME            USED  AVAIL  REFER  MOUNTPOINT
mypool/sheep@all   0      -  2.11M  -
	   

Убедитесь, что вы задали полное имя, включающее часть снимка. Здесь мы просим zfs list отобразить только снимки, а затем передаем ему имя набора данных файловой системы; zfs(8) очень вежливо просит нас быть последовательным в том, о чем мы просим.

# zfs list -t snapshot mypool/sheep
cannot open 'mypool/sheep': operation not applicable to datasets of this type
{не могу открыть 'mypool/sheep': операция на применима к наборам данных этого типа}
	   

Ранее мы применяли флаг -r для отображения набора данных и всех его потомков. Он также работает со списком снимков.

# zfs list -r -t snapshot mypool/second
NAME                  USED  AVAIL  REFER  MOUNTPOINT
mypool/second@all        0      -    96K  -
mypool/second/baby@all   0      -    96K  -

	   

Для просмотра абсолютно всего применяйте -t all.

# zfs list -r -t all mypool/second
NAME                  USED  AVAIL  REFER  MOUNTPOINT
mypool/second         192K  13.5G    96K  legacy
mypool/second@all        0      -    96K  -
mypool/second/baby     96K  13.5G    96K  legacy
mypool/second/baby@all   0      -    96K  -

	   

Если у вас есть много уровней наборов данных вы можете хотеть частичный рекурсивный просмотр. В то время как -r показывает всех потомков, параметр -d ограничивает число уровней вашего просмотра. Ограничим глубину до 1 и вы получите только снимки отдельного набора данных.

# zfs list -d 1 -t snapshot mypool/sheep
NAME                 USED  AVAIL  REFER  MOUNTPOINT
mypool/sheep@all        0      -  2.11M  -
mypool/sheep@snap2      0      -  2.11M  -
mypool/sheep@moresnap   0      -  2.11M  -
mypool/sheep@evenmore   0      -  2.11M  -
	   

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

  Изменение списка вывода zfs

Вы можете управлять тем, какую информацию отображает zfs list при помощи параметра -o и списка колонок или свойств. Когда вы используете -o, zfs list отображает только запрошенную вами информацию.

Взглянем на любой предыдущий вывод zfs list, и мы увидим, что колонка NAME (предсказуемо) отображает имя набора данных. Отобразим только эту колонку при помощи -o. Здесь мы рекурсивно отображаем список всех снимков в mypool, выводя только их имена.

# zfs list -r -t snapshot -o name mypool
NAME
mypool@all
mypool/ROOT@all
mypool/sheep@snap2
mypool/sheep@moresnap
mypool/sheep@evenmore
...
	   

Кроме того вы можете отображать в колонке любое свойство. Здесь мы отображаем некоторые общие свойства файловой системы для каждого набора данных.

# zfs list -o name,atime,exec,setuid
NAME        ATIME  EXEC  SETUID
mypool         on    on      on
mypool/sheep   on    on      on
zroot         off    on      on
zroot/ROOT    off    on      on
	   

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

Наконец, вы можете изменять порядок, которым zfs list отображает наборы данных. Используйте -s и свойство для сортировки по значению свойства. Для обратного порядка сортировки по этому свойству вывода используйте -S и свойство. Перечисляйте несколько свойств по порядку, разделяя их запятыми.

  Вывод списков снимков по умолчанию

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

# zpool set listsnapshots=on zroot
	   

Раз уж вы выполните это, какое- то время оно будет работать, однако, мы абсолютно уверены, что вы выключите это свойство опять (off). Накапливающиеся снимки быстро подавят все остальное.

  Сценарии и ZFS

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

Параметр -p просит zfs(8) и zpool(8) печатать точные значения, а не удобные для пользователя их интерпретации. Пул в действительности не может иметь свободными 2ТБ - это просто число, до которого округляется значение. Использование -p печатает действительное значение вовсей его красе.

Параметр -H просит zfs(8) и zpool(8) не печатать заголовки и разделять колонки единичным символом табуляции, вместо их красивого выстраивания, нравящегося людям. Вы человек, не так ли?

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

# zfs list -t all -pH -r mypool
mypool 2670592 96529122918498304 /mypool
mypool/sheep 2351104 965291229184 2273280 /sheep
mypool/sheep@snap1 77824 - 1224704 -
mypool/sheep@second 0 - 2273280 -
...
	   

Да, это реальные пробелы. Аккуратные колонки предназначены людям, глупо.

 Использование пространства на снимок

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

# zfs list -d 1 -t all -o name,used,refer,written mypool/sheep
NAME                   USED  REFER  WRITTEN
mypool/sheep          10.3M  6.11M    2.07M
mypool/sheep@all          0  2.11M    2.11M
mypool/sheep@snap2        0  2.11M        0
mypool/sheep@evenmore     0  2.11M        0
mypool/sheep@later    2.07M  5.11M    4.07M
mypool/sheep@rewrite  1.07M  5.11M    2.07M
	   

Помните, снимки появляются в порядке по дате создания. Актуальный набор данных появится первым - поскольку он, по- видимому, имеет более новые данные чем любой снимок, который был создан прежде любого из его снимков. Снимок @all является старейшим, затем идует @snap2 и так далее.

Первый снимок, @all, позволяет получить доступ к 2.11МБ данных (столбец REFER). Этот снимок также содержит 2.11МБ вновь записанных данных. Это разница между данным снимком и снимком до него.

Снимки @snap2 и @evenmore не имеют новых данных. Они являются неизменными начиная с первого снимка.

Данные выросли где-то между нашими снимками @evenmore и @later. Снимок @later позволяет вам получить доступ к 5.11МБ данных. Он имеет 4.07МБ новых данных.

Снимок @rewrite также позволяет получить вам доступ к 5.11МБ данных, однако он записал 2.07МБ новых данных. Поскольку объем данных, к которым вы можете осуществить доступ тот же, что и у предыдущего снимка, какие-то из старых данных должны были быть переписаны.

Актуальная файловая система также переписала 1МБ данных. Эти данные теперь содержатся только в снимке @rewrite.

 Доступ к снимкам

Наиболее удобный способ доступа к содержимому снимка состоит в доступе через каталог снимка (snapshot directory), или snapdir. Корень каждого набора данных имеет скрытый каталог .zfs. Этот каталог содержит каталог снимка, который, в свою очередь имеет каталог для каждого снимка.

# ls /mypool/sheep/.zfs
total 1
dr-xr-xr-x  2  root  wheel  2 Mar 29 00:30 shares
dr-xr-xr-x  2  root  wheel  2 Mar 30 16:27 snapshot
# ls -l /mypool/sheep/.zfs/snapshot
total 1
drwxr-xr-x  2  root  wheel  5 Mar 29 00:40 snap1
drwxr-xr-x  2  root  wheel  5 Mar 29 00:40 second
	   

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

  Скрытый Snapdir

Каталог снимка .zfs скрыт по умолчанию. Он не будет отображаться даже если вы выполните ls -lA. Это предотвращает от обхода по нему программ резервного копирования, rsync и аналогичных. Если вы хотите отображать каталог .zfs, установите значение свойства snapdir в visible.

# zfs set snapdir=visible mypool/sheep
	   

Теперь если кто-то выполнит cp -R на наборе данных, рекурсивно копируя все ваши снимки в вашу файловую систему и раздув абсолютно все, скройте его назад, установив свойство snapdir в hidden.

  Монтирование снимков

Вы можете смонтировать снимок очень похоже на то, как вы монтируете какую-нибудь файловую систему.

# mount -t zfs mypool/sheep@snap1 /mnt
	   

Вы не можете получать доступ к снимку через скрытый каталог .zfs пока он смонтирован вручную. Даже смонтированный снимок все еще доступен только на чтение.

 Удаление снимков

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

Создадим новый снимок, а затем удалим его.

# zfs snapshot mypool/sheep@deleteme
# zfs destroy mypool/sheep@deleteme
	   

Это было не так трудно, не так ли?

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

  Выполнения уничтожения вхолостую

Флаг холостой операции noop, -n, выполняет "холостое выполнение" процесса удаления. Он описывает что должно произойти если вы удаляете снимок без его реального удаления. Давайте вернемся к тем нескольким первым снимком, которые мы сделали, и посмотрим что бы произошло, если бы мы удалили первый.

# zfs destroy -vn mypool/sheep@snap1
would destroy mypool/sheep@snap1
would reclaim 72K
	   

Удаление этого снимка вернет только 72кБ пространства. Составляющие этот снимок все еще используются активной файловой системой и/ или другим снимком.

Наш второй снимок переписал некоторые данные из первого снимка. Это изменяет эффект от удаления снимка.

# zfs destroy -vn mypool/sheep@second
would destroy mypool/sheep@second
would reclaim 1.07M
	   

Мы освободим пространство используемое для хранения перезаписанной версии файлов.

  Рекурсия и диапазоны

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

# zfs destroy -rv mypool@all
will destroy mypool@all
will destroy mypool/second@all
will destroy mypool/second/baby@all
will destroy mypool/lamb@all
will destroy mypool/ROOT@all
...
will reclaim 84K
	   

Рекурсивное удаление снимков является лучшим случаем использования -n перед реальным уничтожением каких либо данных (При стрельбе себе в ногу прицеливайтесь тщательнее. Безопасность прежде всего!). Неоднократно мы понимали, что нам нужен снимок через две секунды после его удаления.

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

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

Здесь мы уничтожаем два тестовых снимка. Заметим, что первый снимок определяется его полным именем включающим набор данных: mypool/sheep@myfirstsnapshot. Второй снимок должен быть частью того же самого набора данных и он должен быть снимком, поэтому вам нужно только краткое имя самого снимка: second.

# zfs destroy -vn mypool/sheep@snap1%second
would destroy mypool/sheep@snap1
would destroy mypool/sheep@second
would reclaim 1.14M
	   

Если вы уверены, опустите флаги -vn и вы точно уничтожите ваши снимки:

# zfs destroy mypool/sheep@snap1%second
	   

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

 Откат

Снимки не просто отображают вам как существовала файловая система в определенный момент в прошлом. Вы можете вернуть весь ваш набор данных в его состояние снимка. Собираетесь выполнять обновление? Вначале создайте снимок. Если обновление не работает - просто откатите назад. Воспользуйтесь командой zfs rollback для возврата файловой системы к снимку. Однако когда вы вернетесь назад, вы не сможете пройти вперед снова.

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

# zfs create -o mountpoint=/delorean mypool/delorean
# echo "this is the past" > /delorean/timecapsule.txt
# zfs snapshot mypool/delorean@thepast
# echo "this is the present" > /delorean/timecapsule.txt
# zfs snapshot mypool/delorean@thepresent
# echo "I broke the future" > /delorean/timecapsule.txt
	   

Файл /delorean/timecapsule.txt получил вовнутрь три различных набора текста. Две версии этого текста фиксируются в снимках. Третья не содержится в снимке.

# cat /delorean/timecapsule.txt
"I broke the future"
	   

О, нет, будущее испорчено. Давайте вернемся к настоящему. Выполним zfs rollback и зададим имя снимка, который вы хотите применить.

# zfs rollback mypool/delorean@thepresent
	   

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

# cat /delorean/timecapsule.txt
"this is the present"
	   

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

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

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

# zfs rollback mypool/delorean@thepast
cannot rollback to 'mypool/delorean@thepast': more recent snapshots or bookmarks exist
use '-r' to force deletion of the following snapshots and bookmarks:
{не могу откатить к 'mypool/delorean@thepast': существуют более современные снимки или закладки
применяйте '-r' для принудительного удаления следующих снимков или закладок:}
mypool/delorean@thepresent
	   

Команда zfs rollback может уничтожить для вас все промежуточные снимки если вы воспользуетесь рекурсивным флагом -r. Это не тот же самый вид рекурсии множественных наборов данных, который применяется при создании и уничтожении снимков. Применение rollback -r не откатит назад потомков. Вы должны выполнять откат каждого набора данных отдельно.

# zfs rollback -r mypool/delorean@thepast
# cat /delorean/timecapsule.txt
"this is the past"
	   

Вы вернулись назад во времени и можете теперь попробовать повторить снова рискованное и болезненное обновление. Наши поздравления!

 Нахождение разницы снимков

Иногда вы действительно хотите знать что изменилось между сделанным в определенное время снимком и текущим состоянием. Если сервер базы данных начал разваливаться сегодня в полдень, вы, скорее всего, захотите сравнить состояние файловой системы прямо сейчас со снимком в 11 утра (AM) чтобы увидеть изменения. Вы можете применить find(1) для поиска измененных после создания снимка файлов, или можете воспользоваться diff(1) для сравнения файлов из снимка с файлами в актуальной файловой системе. Однако, ZFS уже имеет эту информацию и делает ее доступной посредством zfs diff.

Чтобы посмотреть на разницу между снимком и актуальной файловой системой выполните zfs diff и задайте в ней имя снимка.

# zfs diff mypool/sheep@later 
M /mypool/sheep/randomfile
	   

Файлы могут быть в четырех состояниях. "-" означает что данный файл был удален. "+" означает, что файл был добавлен. "M" идентифицирует, что файл был изменен. "R" показывает,что файл был переименован. Наш пример здесь показывает, что файл /mypool/sheep/randomfile был изменен после создания снимка.

Вы также можете сравнить два снимка.

# zfs diff mypool/sheep@later @muchlater
M /mypool/sheep/
+ /mypool/sheep/newfile
- /mypool/sheep/zfsbook.html
R /mypool/sheep/date.txt -> /mypool/sheep/olddate.txt
M /mypool/sheep/randomfile
	   

Каталог /mypool/sheep был изменен. Был добавлен файл /mypool/sheep/newfile, а файл /mypool/sheep/zfsbook.html был удален. У нас есть переименованный файл и, опять же, файл randomfile был изменен.

Вы можете даже получить дополнительные подробности. Если вы добавите флаг -t, вывод будет содержать метки времени (timestamp) inode. Флаг -F включает тип данного файла. Проверьте zfs(8) для получения полного списка типов файлов.

 Автоматический режим снимка

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

  Циклическое расписание

Трудная часть планирования создания и уничтожения снимков выясняет как вы могли бы использовать снимки. Кто ваши пользователи? Каким приложениям скорее всего потребуются снимки? Мы не можем ответить на эти вопросы за вас.

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

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

Если у вас существует нужное вам расписание, инструменты ZFS могут помочь вам организовать его.

  Инструменты ZFS

Многие сценарии и пакты программного обеспечения могут управлять в ваших целях снимками ZFS. Мы рекомендуем ZFS tools (https://github.com/bdrewery/zfstools), поскольку он не использует файл настройки. Ему требуется cron(8), но вам не нужно путаться ни с какими zfstools.conf. ZFS tools получают свои настройки из свойств определенных пользователем, установленных в пределах ZFS. Это означает,что новые наборы данных автоматически наследуют свой снимок настроек от своих родителей. Когда система имеет десятки наборов данных, а вы постоянно создаете и удаляете их, наследование настроек сохраняет много времени.

Установим ZFS tools из пакета.

# pkg install zfstools
	   

ZFS tools приходит со многими сценариями и приложениями, но в настоящий момент мы сосредоточимся на zfs-auto-snapshot.

  zfs-auto-snapshot

Сценарий Ruby zfs-auto-snapshot создает и удаляет снимки. Он получает два аргумента, а именно: имя снимка и число таких снимков, которые нужно хранить. Например, выполнение zfs-auto-snapshot frequent 4 создаст рекурсивный снимок с именем frequent и будет хранить четыре снимка каждого набора данных.

В комбинации с cron(8) ,zfs-auto-snapshot позволяет вам создавать любые снимки, которые вы хотите, с любым нужным вам интервалом времени, а затем сбрасывать его по мере его старения.

ZFS tools приходит с crontab по умолчанию для создания снимков по расписанию, который, как надеются разработчики, будет отвечать потребностям большинства людей. Он начинает с установки $PATH, стем, чтобы zfs-auto-snapshot мог находить Ruby. Далее он имеет записи, чтобы создавать снимки каждые 15минут, каждый час, ежедневно, еженедельно и ежемесячно. Давайте рассмотрим все их.

15,30,45 * * * * root /usr/local/sbin/zfs-auto-snapshot frequent 4
	   

zfs-auto-snapshot выполняется каждую 15ю, 30ю и 45ю минуты каждого часа, он создает для каждого набора данных снимок с именем frequent. Когда набор данных имеет более четырех снимков frequent, более старые удаляются, оставляя только четыре снимка.

0 * * * * root /usr/local/sbin/zfs-auto-snapshot hourly 24
	   

На почасовой основе, ровно в каждый час, zfs-auto-snapshot создает снимок с именем hourly. Он оставляет 24 таких снимка, удаляя самые старые.

7 0 * * * root /usr/local/sbin/zfs-auto-snapshot daily 7
	   

Каждый день,через 7 минут после полуночи, zfs-auto-snapshot создает ежедневный снимок. Он оставляет семь ежедневных снимков.

14 0 * * 7 root /usr/local/sbin/zfs-auto-snapshot weekly 4
	   

На 7й день каждой недели, в полночь, zfs-auto-snapshot получает еженедельный снимок. Он сохраняет четыре еженедельных снимка.

28 0 1 * * root /usr/local/sbin/zfs-auto-snapshot monthly 12
	   

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

Данные записи crontab разработаны для /etc/crontab. Если вы используете их в crontab root, вы должны переместить записи пользователя (root) для каждого из них. В любом случае убедитесь, что вы включили переменную PATH чтобы zfs-auto-snapshot мог найти Ruby.

Подгоните имена и расписания для соответствия вашему окружению и предубеждениям. Лукас всегда переименовывает frequent в 15min, поскольку слово frequent двусмысленное. Однако это его личные заморочки, так что можете игнорировать его мысли.

  Разрешение автоматического снимка

Сценарий zfs-auto-snapshot создает только снимки наборов данных, которые имеют свойство com.sun:auto-snapshot установленное в значение true. Наборы данных без этого свойства или при любом установленном для него значении, отличном от true, не будут получать снимки. Установка этого свойства на некий набор данных позволяет потомкам этого набора данных наследовать его.

Здесь мы устанавливаем com.sun:auto-snapshot в корне набора данных нашего пула mypool.

# zfs set com.sun:auto-snapshot=true mypool
	   

При работе zfs-auto-snapshot, он создает снимки каждого набора данных в mypool, причем имя и интервалы предписываются /etc/crontab.

Возможно, некоторым наборам данных не нужны снимки. Например, мы никогда неделаем снимки дерева портов. Чтобы выключить снимки для набора данных и его потомков установите com.sun:auto-snapshot в значение false.

# zfs set com.sun:auto-snapshot=false mypool/usr/ports
	   

Также вы можете запрещать только определенные классы снимков. Не изменяющемуся часто набору данных, вероятно, не нужны снимки frequent и hourly. zfs-auto-snapshot проверяет на наличие под-свойств com.sun:auto-snapshot именуемых после {двоеточия}. Например, свойство, которое управляет вашими почасовыми снимками, называется com.sun:auto-snapshot:hourly. Установите значение этого свойства в false для запрета таких снимков.

# zfs set com.sun:auto-snapshot:frequent=false mypool/delorean
# zfs set com.sun:auto-snapshot:hourly=false mypool/delorean
	   

Теперь zfs-auto-snapshot делает только ежедневные, еженедельные и ежемесячные снимки для этого набора данных и всех его потомков. Вы можете повторно разрешить более частые снимки для определенных потомков установив для них значение данного свойства в true.

Вы также можете решить, что поскольку вам нужны более частые копии /usr/src, поскольку вы работаете с неким важным кодом, вам не нужно сохранять копии старше месяца дерева источника:

# zfs set com.sun:auto-snapshot:monthly=false mypool/usr/src
	   

zfs-auto-snapshot ZFS Tools обрабатывает все циклические замены снимков для вас.

  Просмотр автоматического снимка

Автоматические снимки имеют имена, начинающиеся с zfs-auto-snap с последующим промежутком и штампом времени.

# zfs list -t all -r db/db
NAME                                          USED  AVAIL  REFER  MOUNTPOINT
db/db                                         587M  13.5G   561M  /
db/db@zfs-auto-snap_hourly-2015-04-08-16h00   224K  -       561M  -
db/db@zfs-auto-snap_hourly-2015-04-08-17h00   220K  -       561M  -
db/db@zfs-auto-snap_hourly-2015-04-08-18h00   200K  -       561M  -
db/db@zfs-auto-snap_frequent-2015-04-08-18h45 188K  -       561M  -
db/db@zfs-auto-snap_hourly-2015-04-08-19h00   172K  -       561M  -
db/db@zfs-auto-snap_frequent-2015-04-08-19h15 172K  -       561M  -
db/db@zfs-auto-snap_frequent-2015-04-08-19h30 180K  -       561M  -
db/db@zfs-auto-snap_frequent-2015-04-08-19h45 180K  -       561M  -
db/db@zfs-auto-snap_hourly-2015-04-08-20h00   180K  -       561M  -
	   

  Получение преимуществ при помощи zfs-auto-snap

Не существует ничего магического в именах снимках или расписаниях, используемых zfs-auto-snapshot. Лукас как-то выполнил в командной строке zfs-auto-snapshot hourly 2 и случайно удалил кучу почасовых снимков. Вы можете именовать свои почасовые снимки monthly, а ваши ежегодные снимки daily. Если вы решили отстреливать ненавидящих вас людей и все что вы отстаиваете, то это прекрасный способ решить данную проблему.

 Захваты

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

Используйте zfs hold, имя тега и имя снимка. Имя тега является читаемой человеком меткой для этого определенного захвата.

# zfs hold tag dataset@snapshot
	   

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

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

# zfs hold -r hostages mypool/test@holdme
	   

Команда zfs holds отобразит список захватов на снимке или рекурсивно списки всех захватов в иерархии снимков.

# zfs holds -r mypool/test@holdme
NAME                     TAG       TIMESTAMP
mypool/test@holdme       hostages  Fri Apr 3 19:13 2015
mypool/test/sub1@holdme  hostages  Fri Apr 3 19:13 2015
mypool/test/sub2@holdme  hostages  Fri Apr 3 19:13 2015
	   

Снимок с захватом на нем не может быть уничтожен.

# zfs destroy mypool/test@holdme
cannot destroy snapshot mypool/test@holdme: dataset is busy
{не могу уничтожить снимок mypool/test@holdme: набор данных занят}
	   

Освобождайте захват набора данных при помощи zfs release, задавая имена тега и набора данных.

# zfs release hostages mypool/test@holdme
	   

Теперь вы можете уничтожить снимок. Если бы так просто было с высвобождением ваших фондов с получившим их банком!

Однако, освобождение захвата снимка не освобождает захваты на его потомках.

# zfs destroy -r mypool/test@holdme
cannot destroy snapshot mypool/test/sub1@holdme: dataset is busy
cannot destroy snapshot mypool/test/sub2@holdme: dataset is busy
	   

Чтобы рекурсивно освободить все захваты снимка и его потомков воспользуйтесь флагом -r.

# zfs release -r hostages mypool/test@holdme
# zfs destroy -r mypool/test@holdme
	   

Теперь вы можете уничтожать дочерние наборы данных.

 Закладки

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

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

Закладки являются набором данных, относящимся к снимкам, поэтому мы упомянули о них здесь. Они будут полностью охвачены в книге FreeBSD Mastery: Advanced ZFS.

 Клоны

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

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

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

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

Возможно у вас есть набор данных со многими терабайтами для вашего приложения управления ресурсами предприятия (ERP, Enterprise Resource Planning), однако полностью перезаписываемая копия этого набора данных совсем не требует пространства за исключением ваших изменений.

Дисковое пространство уже не дорого, но клоны делают его еще более доступным.

  Создание клона

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

# zfs clone mypool/sheep@evenmore mypool/dolly
	   

Взглянем на наши наборы данных теперь.

# zfs list
NAME                USED  AVAIL  REFER  MOUNTPOINT
mypool             4.74G  13.5G    96K  none
...
mypool/sheep       10.3M  13.5G  6.10M  /mypool/sheep
mypool/dolly          8K  13.5G  2.11M  /mypool/dolly
mypool/second       192K  13.5G    96K  legacy
mypool/second/baby   96K  13.5G    96K  legacy
	   

Набор данных dolly выглядит как обычный набор данных за исключением его использования пространства. Колонка КEFER показывает, что он имеет 2МБ данных, однако в USED он занимает только 8кБ. Содержащиеся в нем данные берутся из первоначального снимка. Клон потребляет данные только для вновь записываемых данных вне зависимости, будь то новые файлы или перезапись старых.

  Просмотр клонов

Клоны возникают аналогично обычным наборам данных. В zfs list вы не заметите никакой разницы между клономи любымдругим набором данных. (Клоны выглядят как их исходный материал. Это именно то, почему они делают таких хороших ассасинов- убийц. Нет,постойте - плохие клоны. Примите мои извинения.) Однако, клоны записывают свой исходный снимок в свойство origin.

# zfs get type,origin mypool/dolly
NAME          PROPERTY  VALUE                  SOURCE
mypool/dolly  type      filesystem             -
mypool/dolly  origin    mypool/sheep@evenmore  -
	   

Таким образом, клон во всех отношениях появляется просто как обычный набор данных. Свойство origin является единственным способом узнать что это клон. Первоисточник является снимком, из которого был создан данный клон.

Для отслеживания всех клонов в вашей системе воспользуйтесь zfs list и проверьте свойство origin. Мы выделяем все записи, не заканчивающиеся тире.

# zfs list -o name,origin | grep -ve '-$'
NAME          ORIGIN
mypool/dolly  mypool/sheep@evenmore
	   

Это выдает список всех наборов данных, которые происходят из снимков.

  Удаление клонов и снимков

Клоны зависят от блоков, хранимых в снимке- источнике. Наличие клона предотвращает удаления исходного снимка. Если вы попытаетесь удалить снимок, zfs destroy сообщит вам, что существует проблема.

# zfs destroy mypool/sheep@evenmore
cannot destroy 'mypool/sheep@evenmore': snapshot has dependent clones
use '-R' to destroy the following datasets:
{не могу уничтожить 'mypool/sheep@evenmore': снимок имеет зависящие от него клоны
применяйте '-R' для уничтожения следующих наборов данных:}
mypool/dolly@zfs-auto-snap_frequent-2015-04-08-16h15
mypool/dolly
	   

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

# zfs destroy mypool/dolly
cannot destroy 'mypool/dolly': filesystem has children
use '-r' to destroy the following datasets:
{не могу уничтожить 'mypool/dolly': файловая система имеет потомков
используйте '-r' для уничтожения следующих наборов данных:}
mypool/dolly@zfs-auto-snap_frequent-2015-04-08-16h15
	   

Ой, подождите. Клон унаследовал свойство zfs-auto-snapshot от своего родителя, так что наша автоматизация снимка уловила его. Если вы не хотите чтобы над клоном создавались снимки, вы должны выключить это свойство. Вы можете удалять снимки вашего клона вручную, однако zfs-auto-snapshot продолжит создание новых снимков. Вы также можете использовать флаг -r (рекурсии) для уничтожения клона и всех его снимков.

# zfs destroy -rv mypool/dolly
will destroy mypool/dolly@zfs-auto-snap_frequent-2015-04-08-16h15
will destroy mypool/dolly
	   

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

# zfs destroy -v mypool/sheep@evenmore
will destroy mypool/sheep@evenmore
will reclaim 0
	   

Клоны очень мощны, однако они усложняют управление снимками.

  Продвижение клонов

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

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

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

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

Давайте пройдем продвижение клона. Вот мы клонируем набор данных mypool/wooly в набор данных с именем mypool/bonnie и изменяем клон.

# zfs clone mypool/wooly@later mypool/bonnie
# date > /mypool/bonnie/date.txt
# dd if=/dev/random of=/mypool/bonnie/randomfile bs=1m count=8 oseek=4
	   

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

# zfs list mypool/bonnie
NAME            USED  AVAIL  REFER  MOUNTPOINT
mypool/bonnie  8.07M  13.5G  12.1M  /mypool/bonnie
	   

Колонка USED показывает 8МБ новых данных, которые мы записали в наш клон. Колонка REFER показывает набор данных, который содержит 12МБ данных - 4МБ из первоначального снимка плюс новые 8МБ, добавленные нами.

Мы хотим сохранять набор данных bonnie и получить освобождение первоначального набора данных wooly:

# zfs destroy -rv mypool/wooly
cannot destroy 'mypool/wooly': filesystem has dependent clones
use '-R' to destroy the following datasets:
mypool/bonnie@zfs-auto-snap_frequent-2015-04-08-16h30
mypool/bonnie
	   

ZFS знает, что набор данных mypool/bonnie и его снимки первоисточника основываются на наборе данных mypool/wooly. Следовательно, мы применяем команду zfs promote для создания файловой системы bonnie и возвращаем старые наборы данных в наш клон.

Перед продвижением клона выполните zfs list и проверьте использование пространства и происхождение обоих вовлеченных наборов данных.

# zfs list -t all -r mypool/wooly mypool/bonnie
NAME                    USED   AVAIL REFER   MOUNTPOINT
mypool/bonnie           8.07M  13.5G  12.1M  /mypool/bonnie
mypool/wooly            10.3M  13.5G  6.10M  /mypool/sheep
mypool/wooly@all            0      -  2.11M  -
mypool/wooly@moresnap       0      -  2.11M  -
mypool/wooly@later      2.07M      -  5.11M  -
mypool/wooly@rewrite    1.07M      -  5.11M  -
mypool/wooly@muchlater      0      -  6.10M  -
	   

Мы вернемся к этому списку позже. А сейчас продвинем mypool/bonnie.

# zfs promote mypool/bonnie
	   

Продвижение должно работать бесшумно. Давайте опять взглянем на эти два набора данных.

# zfs list -t all -r mypool/wooly mypool/bonnie
NAME                    USED   AVAIL  REFER  MOUNTPOINT
mypool/bonnie           14.3M  13.5G  12.1M  /mypool/bonnie
mypool/bonnie@all           0      -  2.11M  -
mypool/bonnie@moresnap      0      -  2.11M  -
mypool/bonnie@later     1.07M      -  5.11M  -
mypool/wooly            4.14M  13.5G  4.10M  /mypool/sheep
mypool/wooly@rewrite    1.07M      -  5.11M  -
mypool/wooly@muchlater      0      -  6.10M  -
	   

Снимок, на котором основан mypool/bonnie и все более старшие чем первоначальный снимки теперь относятся к mypool/bonnie. Более новые снимки mypool/wooly, сделанные после создания снимка mypool/bonnie все еще относятся к mypool/wooly.

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

# zfs destroy -rv mypool/wooly
will destroy mypool/wooly@muchlater
will destroy mypool/wooly@rewrite
will destroy mypool/wooly
	   

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

 Безопасное управление клонами, снимками и рекурсией

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

Флаги -nv являются жизненно важными для безопасного администрирования систем. Всякий раз, когда малейший мысль уничтожить набор данных начинает рассматривать возможность прохождения в вашем рассудке, сделайте холостое выполнение с -nv. Ознакомьтесь с тем, что команда destroy фактически устранит. Прочитайте весь список. Вы можете обнаружить, что ваш рекурсивный destroy протянется по потоку клонов, который простирается по всему пути вдоль пула.

Проверяйте переде своим прыжком. Всегда.

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