вторник, 29 сентября 2009 г.

VirtualBox, ZFS и зеркалирование

Намедни я дважды напоролся на одну проблему, связанную с гостевым Solaris 10 на VirtualBox, установленной на ZFS.

Оказывается, в такой среде ZFS не любит - и еще как не любит! - дефрагментации дисков хозяйской ОС.

После выполнения дефрагментации файлов *.VDI пулы бьются, с неустранимыми ошибками. Если не позаботиться сделать снапшотов и не сохранить из за пределами виртуальной машины или при отсутствии зеркалирования - все пропало, шеф, все пропало! ;)

Не надо спешить кидать помидоры и орать "Sun must die!". Горячки не порите.

Оставим в покое особенности поведения VirtualBox на различных хозяйских ОС.

Давайте не спеша разберемся, что именно пропало и почему.

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

root @ pegasus / # zfs get checksum data
NAME PROPERTY VALUE SOURCE
data checksum on default

включенная по умолчанию. Все верно.

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

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

root @ pegasus / # zfs get copies data
NAME PROPERTY VALUE SOURCE
data copies 1 default

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

Второй способ, более православный - но и более дорогостоящий - зеркалирование пулов:

root @ pegasus / # zpool status data
pool: data
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
mirror ONLINE 0 0 0
c2t1d0 ONLINE 0 0 0
c2t0d0 ONLINE 0 0 0

errors: No known data errors

В такой конфигурации ZFS приобретает свойство self-healing, основанное при единичных логических сбоях на автоматической замене поврежденных блоков на целые, берущиеся с зеркала (зеркал). При этом, если повреждения физические (как было в моем случае - после пересборки файловых фрагментов родительской ОС ZFS посчитал блоки сбойными), то это вылечивается процедурой zfs scrub.

Как известно, scrub и ресильверинг (resilvering) - кровные родственники, причем если при отсутствии зеркал scrub всего лишь проверяет контрольные суммы (неповрежденных блоков ему взять просто неоткуда), то при наличии зеркала поврежденные блоки немедленно извлекаются с зеркала и кладутся на место. Если нижележащее железо физически в порядке, то процедура ресильверинга (что реально выполняла ZFS - скруббинг или ресильверинг - показывает команда zpool status) завершается очень быстро и пул снова приходит в целостное состояние.

Иначе говоря, если попытаться проделать фокус с выносом ZFS-пула мусором из /dev/urandom на незеркалироваанном пуле, то вы убьете его быстро и необратимо. Однако в случае зеркал восстановление логических повреждений происходит в реальном времени и закончится как раз в момент окончания выполнения команды dd.

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

Следует учитывать еще аспект производительности. Зеркалирование ZFS с дисками (устройствами) физически подключенными к одному контроллеру означает, как правило, деградацию производительности. Размещение частей зеркал на одних и тех же дисках означает то же самое.

В описываемом случае с VirtualBox диск родительской машины физически один, разбитый на два раздела по административным соображениям:

C:\...инистратор\.VirtualBox\HardDisks>dir
Том в устройстве C имеет метку SYSTEM
Серийный номер тома: ECF8-A9D1

Содержимое папки C:\Documents and Settings\Администратор\.VirtualBox\HardDisks

27.09.2009 02:49 [dir] .
27.09.2009 02:49 [dir] ..
29.09.2009 11:08 8 941 289 984 pegasus_data_disk1.vdi
29.09.2009 11:08 6 742 409 728 pegasus_disk1.vdi
2 файлов 15 683 699 712 байт
2 папок 4 529 758 208 байт свободно

D:\.VirtualBox\HardDisks>dir
Том в устройстве D имеет метку DATA
Серийный номер тома: 14E1-00B2

Содержимое папки D:\.VirtualBox\HardDisks

27.09.2009 02:54 [dir] .
27.09.2009 02:54 [dir] ..
29.09.2009 11:08 9 010 496 000 pegasus_data_disk2.vdi
29.09.2009 11:08 6 382 748 160 pegasus_disk2.vdi
2 файлов 15 393 244 160 байт
2 папок 33 612 677 120 байт свободно

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

Данная конфигурация позволяет лишь наделить пулы гостевой ОС способностью к восстановлению (а зеркала корневого пула - еще и способностью загрузиться с менее поврежденного зеркала для выполнения ресильверинга).

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

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