Жаренный ZFS

Автор: | 20.05.2011

Пару дней назад, ночью, случилась беда на одном сервере с FreeBSD 8.2 и двумя зеркальными пулами ZFS. А случилось следующее — у блока питания порвался хомут, которые держал вместе провода. Порвался и упал, тем самым заклинив вентилятор. В добавок к этому начинающаяся жара, четыре жёстких диска и запустившаяся плановая проверка целостности данных одного из пулов. Утром сервер был обнаружен жутко горячим (руку с трудом можно было держать на корпусе) и постоянно перезагружающимся из-за kernel panic в момент попытки монтирования ZFS. Я уж было подумал, что по совокупности всех факторов данные превратились в фарш…
Далее пишу тезисно, т.к. подробно записывать все команды и результат их выполнения возможности не было.

Устранив причину перегрева стал изучать что же стало с системой в целом и дисками в частности. Несмотря на такой сильный нагрев, с виду и по тестам электроника была живая, можно начинать разбираться непосредственно с пулами. Гружусь с LiveCD, пытаюсь импортировать первый пул:

# zpool import -f zroot

Паника! Перезагружаюсь, пытаюсь со вторым:

# zpool import -f tank

На этот раз успешно. Проверяю целостность данных:

# zpool scrub tank

Через несколько часов проверка закончилось, пара ошибок была исправлена. На этом можно закончить с ценным архивом семейных фото:

# zpool export tank

Возвращаюсь к первому пациенту. Первым делом прощупал через dd один из дисков пула — данные читаемыми, смог различить несколько скриптов и библиотек, что определенно радует и дарит надежду. Далее решил проверить один из найденных на просторах Интернета способ. При загрузки с CD переходим в меню загрузчика (клавиша 6):

OK set vfs.zfs.recover=1
OK boot

После загрузки пробую такую команду:

# zdb -e -bcsvL zroot

Ругается на неверный hostid. Смотрим какой же нужен, выставляем его и пробуем снова:

# zdb -l /dev/gpt/disk1 | grep hostid
# sysctl kern.hostid=<подставляем_из_результата_прошлой_команды>
# zdb -e -bcsvL zroot

Пошуршав несколько часов zdb вывалилась в корку. Жаль, была надежда.

Зная, что во FreeBSD продолжается активная работа надо ZFS, решил опробовать новый код. Быстрый поиск показал, что уже есть готовый патч v28 под 8.2. Ну что же, попробуем. Достал из шкафа запасной винчистер и сделал на него quick install. После успешной загрузки можно накатить патчик и пересобрать систему:

# cd /cdroom/8.2-RELEASE/src
# ./install.sh all
# cd /usr/src
# fetch http://people.freebsd.org/~mm/patches/zfs/v28/releng-8.2-zfsv28-20110317.patch.xz
# xzcat releng-8.2-zfsv28-20110301-nopython.patch.xz | patch -E -p0
# make -j16 buildworld buildkernel
# make installworld installkernel
# shutdown -r now

После успешное перезагрузки пробую импортировать пул:

# kldload zfs
# zpool import -fFX zroot

Успех! Немного неожиданно, но уже радует. Запускаю проверку целостности данных:

# zpool scrub zroot

И вот, через пару часов, когда до завершения проверки оставалось каких-то 3 минуты… kernel panic. Хорошо, перезагрузился и запустил сканирование поверхности обоих дисков. На удивление никаких дефектов не найдено. Снова загружаю систему и останавливаю проверку пока она снова не рухнула:

# zpool scrub -s zroot

Из этого стало ясно, что какие-то из данных содержат критические ошибки. Какие именно ошибки и где разбираться времени нет, надо как можно быстрее реанимировать всю систему в целом. Начинаю постепенное копирование всех данных. Через какое-то время удалось выяснить примерное расположение файлов, при попытки доступа к которым происходит падение системы. На этом этапе уже было спасено около 90% информации. После нескольких падений из-за попытки скопировать битые данные пул отказался импортироваться вызывая всё тот же kernel panic как и в самом начале разбирательств. Но что самое интересное — система с этого пула стала загружаться.

Решил снова попробовать загрузиться с LiveCD — на удивление результат успешный, пытаюсь докопировать оставшиеся данные. В конечном итоге пришлось несколько раз перезагружаться между установленной системой с патчем для v28 и обычным LiveCD, но в итоге абсолютно все необходимые данные были успешно спасены. Не стал копировать лишь некоторые части, благо они легко восполняемые (дерево портов, исходные коды, пара клеток и т. д.).

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

# dd if=/dev/zero of=/dev/ad10; \
# dd if=/dev/zero of=/dev/ad12

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *