Использование ZFS on Linux в некоторых случаях может привести к необратимой потере данных. Не во всех случаях корень зла в самом ZoL, да и собственно потеря данных возможна в случае совместного использования разделяемого хранилища на нескольких системах, но давайте по порядку.
Первая проблема связана с тем, ZoL при загрузке может самостоятельно, т.е. без выполнения пользователем команды zpool import
, импортировать пул на подключенном устройстве. Так, например, у меня ZoL сам импортировал свежесозданный на FreeBSD пул на флешке, которая была подключена в момент загрузки системы. Результатом может стать:
- Если на пуле есть файловые системы с жёстко указанными точками монтирования, могут быть перемонтированы стандартные каталоги, такие как
/sbin
, а в смонтированных каталогах вообще могут оказаться исполняемые файлы от другой операционной системы.
- Пользователь может и не знать о том, что пул был без его ведома импортирован, и отключить устройство с пулом. Скорее всего данные на пуле при этом не повредятся, а вот системе может стать не очень хорошо.
Вторая проблема связана с тем, что ZFS для определения был ли пул импортирован на какой либо системе записывает на пул hostid
импортировавшего узла. На Solaris и FreeBSD уникальность hostid
худо-бедно обеспечивается, а вот в различных дистрибутивах Linux с этим всё гораздо хуже. В Linux библиотечная функция gethostid(3)
в первую очередь пытается прочитать содержимое файла /etc/hostid
, если он отсутствует, то пытается отрезолвить имя узла и использовать полученный IP в качестве идентификатора, иначе возвращается 00000000
. В, например, Oracle Enterprise Linux файл /etc/hostid
автоматически не генерируется, и в момент импорта пула hostid
вполне может оказаться равным 00000000
. ZFS же использует такой идентификатор как обозначание, что пул не был ни кем импортирован, т.е. такой пул можно спокойно импортировать второй раз. В Debian файл /etc/hostid
генерируется, но в большинстве случаев туда записывается идентификатор 007f0101
. А в результате при использовании разделяемого хранилища Вы сможете спокойно повторно импортировать пул на другом сервере и даже не заметить это.
Для борьбы с этой проблемой достаточно обеспечить уникальность hostid
на всех узлах с ZoL. В Oracle Enterprise Linux для этого можно воспользоваться командой genhostid(1)
. Если разработчики дистрибутива забыли её положить, то можно выполнить:
dd if=/dev/random of=/etc/hostid bs=1 count=4
Третья проблема проявится в случае, если Вы попытаетесь построить отказоустойчивый кластер используя ZoL. Для получения проблем достаточно выполнения следующих шагов:
- Импорт пула на первом (активном) узле кластера
- Останов работы первого узла по какой либо причине - kernel panic, аппаратная проблема и т.д.
- Импорт пула на втором (резервном) узле кластера
- Запуск первого узла
После выполнения этих шагов, даже если Вы обеспечили уникальность hostid
на них, пул будет импортирован на обоих узлах. В Solaris и FreeBSD эта проблема отсутствует, и в ZoL, судя по спискам рассылки, эта проблема появилась не очень давно, но на текущий момент она всё еще актуальна.
Последние две проблемы могут привести к двойному импортированию одного пула на нескольких системах, и, соответствено, устройства, хранящие данные пула, должны быть доступны нескольким системам, через, например, FC-AL, SAS, iSCSI или т.д. Двойное импортирование рано или поздно приведёт к разрушению целостности метаданных пула и полной надоступности данных на нём:
# zpool import
pool: tank
id: 9400711421901820791
state: FAULTED
status: The pool metadata is corrupted.
action: The pool cannot be imported due to damaged devices or data.
see: http://zfsonlinux.org/msg/ZFS-8000-72
config:
tank FAULTED corrupted data
sdb ONLINE
По достижении такого успеха можно пытаться восстановить данные с помощью команды zdb
, но задача эта не для слабонервных.