技術

ZFSのプールがインポート出来なくなったけどなんとかなりそう

この記事に関連するかもしれない記事

現状ではまだ一部のデータは救出出来ない可能性が残ってるものの、最終的にはほとんどのデータが救出できそうではあります。
最重要データは置いてなかったので全部消えても喪失感だけで実害は大きくなかったかもしれませんが、今回かなり焦りました。

とりとめのない内容だし、何かのHow toになるとも思えないんですが、一応メモとして出来事を書き連ねておきます。

経緯

2TBのディスクx6のraidz2にZILとL2ARCを追加したプールの空きが少なくなってきた(使用率95%ほど)ので、不要な巨大スパースファイル2つ(iSCSIターゲット用のディスクイメージ、合わせて1.5TBほど)を消去。
消去した時点で、空き容量が回復しないことに気づいた。
しかし以前も同じようなことがあり、そのときは空き容量が回復しない事以外の問題はなく、最終的にsend/recvで他のプールに移したときに自動的に問題は解消。

それから2日後、やはり空き容量が回復しない事が気になったので、とりあえずサーバー(FreeNAS 0.7.5 9S-9545 ZFS v28)を再起動。
すると起動プロセスの途中でHDDのアクセスランプが点きっぱなしになりハング(してるように見えた)。

もう一回起動しなおして、起動中の画面を見てたらどうもzpool import tank的な処理が内部で行われているであろうタイミングでハングしてる様子。

FreeNASのCDから起動して、zpool importで実際にインポートせずにプールを参照してみると、プールの状態はONLINEになってて特にエラーも発生していない様子。
しかしそこでzpool import -f tankとして実際にインポートしようとするとやはりHDDアクセスランプ点きっぱなしでハングしてしまう。
ハングといってもOS自体を巻き込むわけではなく、zpoolプロセスが強制終了出来なくなる程度。
そしてハング中は、空きメモリがどんどん減って、Wiredがどんどん増えていく状態。

HDDのS.M.A.R.T値をチェックしてみても、1つのディスクにCRC Errorが2と記録されてた(安いケーブルのせいかな)点以外は、気になるところはなかった。
特に全ディスクで不良セクタの発生がゼロだったので健康そのものに見えた。
一応メモリのテストもしたけど問題無し。

再度FreeNASのCDから起動して、zpool importしてプールの情報だけ参照してみると、キャッシュデバイスだけデバイス名がdsk/ada1s2になってる事に気づく。(他のデバイスにはdsk/が付いてない)

ZFSによって自動的に無効化されないような微妙な問題がキャッシュデバイスに起きてるのかと思い、まぁキャッシュだからとそのディスクを抜いて起動することに。
同じディスクの別パーティション(ada1s1)にZILが載ってるのでそれも使えなくなるけど、zpool import -m tankでZIL無しインポート出来るのは知ってたのでGO。

しかし起動後zpool import -m tankとやってもやはりハング。

そのまま再起動して、zpool importで参照してみるとZILは当然消えてるが、キャッシュの表示が残ってて、デバイス名の部分がなにやらGUID的なものに。
zpoolラベルのキャッシュの部分が壊れたのかなと思い、zdb -l tankしてみると、キャッシュデバイスのエントリだけ表示されず。

ここでキャッシュ関連の管理情報に問題があると思い込み、しばらくその方向で悩む。

しばらく悩んだ後、そもそも正常な状態のzpool importやzdb -l tankの表示を知らない事を思い出したw
そこで仮想マシンで同じ構成のプールを作ってzpool importやzdb -l tankをやってみたところ、ハングするプールのzpool importやzdb -l tankの表示には全く問題ない事が判明。

ここで少しホッとしたものの、2つの可能性が思い浮かぶ。

ひとつは、外部からインポート無しで参照できる情報には問題が無いので、プールの状態は思ってるほど重篤じゃないかもということ。
もうひとつは、外部から参照できる情報には問題が無いにも関わらずハングするということは、メタデータの破損のような、修正方法を知ってれば比較的対処しやすいものが原因ではなく、内部にほとんど修復不可能なくらい重篤な原因があるかもしれないということ。

後者だと完全にお手上げ(そこまで重要なデータは置いてなかったので主にコスト的な問題)なので、前者と仮定して作業することに。

とりあえずディスクを戻してからお決まりのzpool import -F tankをやってしばらく待ってみると、rewindが完了したとの表示が。
その後もやはりそのままハングしてしまうが、rewind出来たということは中の構造はそんなに壊れてないはずと確信。

しかしここからzpool import -FX tankとかも試したが全く事態は進展せず。

半分諦めて、zpool import tankでハングさせたまましばらく放置してたら、メモリを食いつぶしてOSごと停止。
それを何回かやってみるとメモリが枯渇するまでの時間が10分から1時間半と結構幅があった。(メモリは8GB)

OSが停止するほどメモリを食いつぶすなんて、zpoolのZFSの暴走としか思えなくて、自分でなんとか出来る範囲を超えてると思ったけど、ダメもとで別のOSで試してみることに。

同じFreeBSD系だと同じ問題が起こる可能性が高いので、NexcentaStorを試してみた。
しかしインストールしようとするとハードウェアの認識がボロボロでまともに使うのに手間がかかる雰囲気がしたのでそうそうに諦めて、PC-BSD 9.0のLive DVDを試してみた。

PC-BSDでも事態は進展しなかったが、どうせならちゃんとしたOSでやろうと思いFreeBSD 9.0を別のHDDにインストール。
PC-BSDでも良かったんだけど、zpool import tankがメモリを食いつぶすまでの時間を少しでも長くしたかったので、GUI使わないし普通のFreeBSDでいいやということで。

何度かFreeBSDでzpool import tankをやって待ってる間にふと、プールの情報から一歩進んでデータセットの情報が見れると少し希望が持てるかなと思い、zfs listをやってみるとそれもハング。
まぁ裏でzpool import tankがハングしてる最中だし、インポートが完了してないプールはzfs list出来ないよねと思い放置。

それから数分たって見てみると、あいかわらずzpool import tankはハングしたままにも関わらず、zfs listの結果が返ってきてることに気づく。
しかも返ってきてる情報も正常な頃と同じ。

これで少し希望が出てきて色々試してみたら、zpool import tankして5分〜10分待つと、インポート済みのプールに対して使えるコマンドの多くが使えるようになることに気づいた。

その状態でマウントポイントをみたらデータセットのディレクトリが出来てる事に気づく。
しかしディレクトリの中は全部空。
データセットの情報は残ってても中身は全部破損して消えたのかなと嫌な考えが頭の中をよぎるが、インポート済みのプールに対して実行出来るコマンドがいくつか使えるなら復旧に役立てられるかもと考えた。

ここに来て今回の症状をハングを呼ぶのは少し違う気がしてきたが、説明のためここではそのまま記す。

未だキャッシュデバイスの事が気になってたので、zpool removeで取り外してみたら出来た。
ついでにZILも。
プールの構成がシンプルな方が少しでも復旧の可能性が高まるかなとも思ったので。

さらにzpool listやzfs listをやって気づいた事だが、ハング中少しずつあるデータセットの空き領域が増えていってるようだった。
そのデータセットは、2日前に消した巨大なスパースファイルを置いてたデータセットである。

さらに今回のプールには全部で8つのデータセットがあり、そのデータセットはアルファベット順で先頭である。

もしかして、プールのインポートは正常に出来るけどその後の自動マウント処理で最初に処理されるデータセットにおいて、空き領域回復の(メモリを食いつぶすという問題はあるものの、ある意味正常な)処理が実行され、その待ちで後ろに控える他のデータセットがマウントされてないだけじゃないか?と思い至った。

ということでさっそく、zpool import tankしてちょっと待った後、zfs mount tank/<他のデータセット名> としてみたら、マウント出来たーーー!!!

中身も無事のよう。

例のデータセットだけはマウントしようとするとハングしてしまうけど、その間徐々に空き領域が回復していってるので、もしかしたら消したスパースファイルの分を回収できたらマウントできるのかななんて思ってる。
このデータセットには、10年以上前から毎年のように買い換えてきたPCのディスクの内容そのままが保存されてたりするんだけど、ほとんど後から見返したことがないので、最悪消えてもそんなに痛くはないかもしれない。

まとめ

それにしてもZFSを使ってると今回のようにやば気な問題がたまに起こるんだけど、中のデータが消えないところは素晴らしい。
といっても今回例のデータセットがマウント出来るようになるかどうかでその辺の評価も変わるけど。

メモリを食いつぶすまでに平均1時間以上かかって、50GBぐらいしか回収できないみたいなので、最終的な結果がどうなるか分かるまでに時間がかかりそうです。

コメント

こんにちは!

先日、1TB弱のスパースボリュームをzfs destroyしたところ、kernelが逝ってしまい、
poolをimportできないという症状に陥りました。

poolの大きさはほぼ10TB・・
その全部のコピーを持ってるはずもなく、涙目になって、ほぼ諦めかけたんですが・・
勇気を出していろいろ調べてみたところ、このブログに出会い、
無事importすることに成功しました!データも壊れていません。

感謝の気持ちでいっぱいです。本当に助かりました。
(拙い日本語で申し訳ありません・・)

どうも!

定量的でない記事ばかりで恐縮ですがお役に立ててよかったです!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です



※画像をクリックして別の画像を表示

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください