среда, 19 сентября 2012 г.

Анатомия ZFS часть II


При написании данного цикла статей использовался документ ZFS On-Disk Specification,Sun Microsystems


1.1.2 Метки виртуальных устройств

Каждое физическое виртуальное устройство в пуле хранения имеет структуру размером 256 Кбайт, которую называют меткой физического виртуального устройства (vdev label).
Метка описывает собственно физическое виртуальное устройство и другие физические устройства, входящие в состав общего логического виртуального устройства верхнего уровня. Например, метка устройства A на рис.1 содержит описания устройств B и зеркала M1.
Метки несут двойную функциональную нагрузку – во-первых, посредством их предоставляется доступ к устройствам, а во-вторых, они используются для проверки целостности и доступности устройств.
Для того, чтобы гарантировать доступность и сохранность меток, используется специальная модель высоконадежного стадийного обновления. Надежность обеспечивается наличием на устройстве четырех меток на каждом физическом устройстве, входящем в состав пула. Эти копии идентичны для одного устройства, однако различны для остальных устройств пула. Во время обновления меток используется двухстадийная транзакционная схема, обеспечивающая наличие хотя бы одной корректной метки на диске.


Рис.2. Расположение меток на устройстве объемом N

Так как обновление выполняется очень быстро, можно утверждать, что копии идентичны и могут использоваться для доступа к пулу. Каждый раз, когда устройство добавляется в пул, ZFS помещает две копии меток в начале устройства, и две в конце.
Подобное размещение меток позволяет снизить вероятность разрушения всех копий единовременно и потерю доступа к устройству, в частности, в ситуациях случайной перезаписи всего устройства (например, в случаях ошибочного добавления устройства к подкачке или ошибочного стирания устройства командой dd).
Метки физических виртуальных устройств не могут использовать семантику записи-в-копии (copy-on-write), как все остальные структуры ZFS, поскольку находятся на фиксированных позициях на диске и имеют фиксированный размер. Это означает, что метки физически перезаписываются при обновлении, что может привести к сбою при записи и потере устройства. Для того, чтобы минимизировать риск подобного происшествия, запись меток выполняется в две стадии. Первая стадия записывает четные метки (L0 и L2), вторая – нечетные (L1 и L3).
Данная схема позволяет с высокой вероятностью обеспечить сохранность и целостность хотя бы одной метки, используемой для доступа к виртуальному физическому устройству.

Замечание: Существует, однако, физическая возможность нарушения структуры файловой системы, связанной с подобной схемой размещения меток.
Расположение пар меток в начале и в конце физического дискового устройства пордазумевает, что размер диска фиксирован. В большинстве случаев именно так и быват. Однако, в случае виртуального диска переменного размера, например, в виртуальных машинах, при расширении диска ZFS не может автоматически переместить концевые метки вслед за границей файла, содержащего виртуальный диск.
Подобное поведение не является чем-то необычным. Файловая система не обязана обладать интеллектуальным поведением по отношению к физическим устройствам, на которых она работает; обычно исходят из допущения, что физическое устройство имеет фиксированный размер и стабильные параметры.
Данный случай не подпадает под легитимное изменение размеров файловых систем.
При изменении объема файловой системы, в случае увеличения это проще всего – достаточно скорректировать метаданные, при уменьшении обычно выполняют перестроение всей системы через резервные копии.

1.1.3 Внутри виртуального устройства

Метки являются отправной точкой большинства *NIX-файловых систем. Они либо содержат ключевую информацию о дисках, либо являются краеугольным камнем всей файловой системы.
Метка виртуального устройства ZFS состоит из четырех частей фиксированного размера: 8 Кбайт пустого пространства, 8 Кбайт занимает заголовок загрузочной информации, 112 Кбайт предназначено для пар «имя-значение» и 128 Кбайт занимают структуры уберблоков по 1 Кбайт каждый.

1.1.3.1   Пустое пространство и VTOC

ZFS поддерживает оба типа меток – VTOC (Volume Table of Contents) и EFI (Extended Firmware Interface) как корректные описания структуры дисков. Метки EFI не записываются на диск как часть слайса, в то время как VTOC должна занимать первые 8 Кбайт слайса 0. Таким образом, первые 8 Кбайт метки ZFS зарезервированы для VTOC.

1.1.3.2  Заголовок блока загрузки

Заголовок загрузочной информации объемом 8 Кбайт зарезервирован для использования в будущем.

1.1.3.3  Список пар «имя-значение»

Последующие 112 Кбайт содержат пары «имя-значение», описывающие виртуальные устройства и связанные с ними виртуальные устройства (иными словами, это описанное в виде матрицы дерево виртуальных устройств). Все пары хранятся в виде XDR-кодированных списков.
Каждый элемент списка содержит тип устройства (disk, file, mirror, raidz, replacing, root), путь устройства, глобальный идентификатор устройства, данные метаслаба, объем данных, могущих быть выделенными на устройстве, список дочерних элементов для данного устройства и некоторые другие данные.

1.1.3.4   Уберблок (uberblock)

Непосредственно за парами «имя-значение» дерева устройств следует массив уберблоков, которые представляют из себя порции информации, необходимые для доступа к данным пула. Уберблок функционально аналогичен суперблоку UFS. В каждый момент времени активен только один уберблок пула. Каждый уберблок с наибольшим номером группы транзакций в пуле и валидной контрольной суммой SHA-256 является активным уберблоком.
Чтобы гарантировать постоянный доступ к активному уберблоку, он никогда не перезаписывается. Наборот, все обновления уберблока выполняются над другим элементом массива уберблоков. Таким образом, уберблоки – это первый элемент структуры ZFS, для которого действует идеология «Write-on-copy».
В процессе записи нового уберблока, все группы транзакций и изменения отметок времени выполняются над новым активным уберблоком в рамках одиночной атомарной транзакции. Уберблоки перезаписываются по алгоритму round-robin между всеми виртуальными устройствами пула.


Рис.3. Уберблок

Уберблок хранит данные в родной для машины последовательности байт (endianness) и содержит следующее:
 
Магическое число, описывающее устройство как содержащее данные ZFS и последовательность байт машины. Представляет собой 64-битное целое, содержащее значения 0x00bab10c для Big Endian машин и 0x0cb1ba00 для Little Endian машин.
Замечание: Данное значение используется для обеспечения независимости доступа к данным пула ZFS на машинах с различной последовательностью байт данных, тем самым обеспечивается гибкость и транспортируемость пулов между машинами с различной архитектурой.

Версия уберблока. Это значение используется для определения формата хранения данных на диске. В текущей версии содержит значение 0x1. Содержание данного поля совпадает со значением поля «version» соответствующего элемента массива «имя-значение», описанного в разделе 1.1.3.3.

Транзакционная группа. Все записи в ZFS группируются в транзакционные группы. Данное число содержит номер транзакционной группы, для которой был записан данный уберблок. Номер транзакционной группы должен быть больше или равен значению «tgx» соответствующего элемента массива «имя-значение», чтобы быть валидным.
Контрольная сумма глобальных идентификаторов устройств пула, используемая для проверки доступности виртуальных устройств пула. ZFS обходит все дочерние виртуальные устройства пула и сравнивает сумму с записанным значением. Если они совпали, все устройства пула доступны.

Отметка времени, когда уберблок был записан, в формате Универсального Координированного Времени (UTC) в секундах с 1 января 1970 года.

Указатель корневого блока - структура, содержащая местонахождение MOS (Meta Object Set, множество мета-объектов). Фактически это прямая ссылка на связанные метаданные файловой системы. Подробнее описана в разделе 1.4.

Замечание: Как следует из вышеприведенных описаний, уберблоки являются вершиной структуры данных, обеспечивающей транзакционную семантику ZFS.

(продолжение следует)