先日、ZFSプールを処理するときに重大なエラーをいくつか発生させ(エラーの修正に関するオンラインアドバイスを読み間違えている間)、誤ってbackup
という名前の既存の2ドライブミラープールを「作成」しました。 (はい、私はそれが不平を言った後、-f
オプションを使用しました。そして今、私は二度とこれをやらないことを知っています。)
いずれにせよ、数か月前に同じプールから3番目にミラーリングされたドライブを取り出したのは、それが古くなっていて、失敗するまで待たなかったためです。そのため、このドライブを交換して、プールを復元するために使用できると思いました。 (私は過去数ヶ月のバックアップを見逃しているだけで、これは主にこのプールが使用されるものです。)
ただし、この1つの古いドライブではプールをインポートできないようです。最初は、誤って作成した(そして破棄した)新しいbackup
プールとの名前の競合に関係があるのではないかと最初は思いました。しかし、GUIDを介してインポートしようとしても、何も得られません。
これは、zdb -l/dev/sdb1(3番目のドライブ)からの出力です。
------------------------------------
LABEL 0
------------------------------------
version: 5000
name: 'backup'
state: 0
txg: 0
pool_guid: 3936176493905234028
errata: 0
hostid: 8323329
hostname: [omitted]
top_guid: 14695910886267065742
guid: 17986383713788026938
vdev_children: 1
vdev_tree:
type: 'mirror'
id: 0
guid: 14695910886267065742
whole_disk: 0
metaslab_array: 34
metaslab_shift: 33
ashift: 12
asize: 1000197324800
is_log: 0
create_txg: 4
children[0]:
type: 'disk'
id: 0
guid: 17914838236907067293
path: '/dev/sdd1'
whole_disk: 0
DTL: 143
create_txg: 4
children[1]:
type: 'disk'
id: 1
guid: 17986383713788026938
path: '/dev/sdb1'
whole_disk: 0
DTL: 141
children[2]:
type: 'disk'
id: 2
guid: 1683783279473519399
path: '/dev/sdc1'
whole_disk: 0
DTL: 145
create_txg: 4
features_for_read:
com.delphix:hole_birth
com.delphix:embedded_data
create_txg: 0
labels = 0 1 2 3
したがって、zdbによると、ドライブとドライブ上のプールデータは変更されていないようです。ただし、プールをインポートすると(-f
や-F
でも)、「インポートできません...そのようなプールは利用できません」というエラーが発生するだけです。上記の情報でさまざまなGUIDも使用してみました(GUIDが適切なものであるかどうかわからなかったため))、これらのコマンド(たとえば、zpool import 3936176493905234028
)は取得しません「そのようなプールは利用できません」メッセージ以外のもの。
そのドライブを削除してから新しいバージョンのLinux OSをインストールしました。そのため、古いOSから回復できた古いzpool.cache
ファイルを使用すると、何かがうまくいくと思いました。しかし、コマンドzpool import -c zpool.cache
は次のものを提供します。
pool: backup
id: 3936176493905234028
state: UNAVAIL
status: One or more devices contains corrupted data.
action: The pool cannot be imported due to damaged devices or data.
see: http://zfsonlinux.org/msg/ZFS-8000-5E
config:
backup UNAVAIL insufficient replicas
mirror-0 UNAVAIL insufficient replicas
sdd1 FAULTED corrupted data
sdc1 FAULTED corrupted data
これはやや予想されることです。これらは、createコマンドによってプールが上書きされた2つのディスクです。ただし、sdb1はそこにある可能性のあるドライブとしてはリストされていません-おそらく、ディスクを取り出した後にプールから削除したためと思われます。それにもかかわらず、私はsdb1に古いミラーリングされたデータの完全なコピーを持っていると思います、そしてzdbは同意します。なぜインポートされないのですか?
他に何を試すかについての提案はありますか?実行するその他の診断コマンド?
注:私は Server Faultでこれについて尋ねる (私の状況の詳細についてはリンクを参照)を試しましたが、フィードバックは得られず、特定のLinux実装が方法を理解する上で重要である可能性があることに気付きましたこれを解決します。アドバイスや提案をいただければ幸いです。
更新:私は問題を発見したかもしれません。 detach
コマンドを発行する前に、スペアドライブを取り外したと思いました。そして、私がまだラベル情報を見ているという事実(他のオンラインソースがdetach
がプールのメタデータを破壊することを示しているように見えるとき)はそれを確認しているようです。単にzdb -l backup
と入力してラベル情報を取得(そして-u
を使用してuberblock情報を取得)できるので、デバイスを明示的に指定しなくてもzfsはプールを表示するようです。何らかの理由でインポートしたくありません。
しかし、私はdetach
ステータスについてもはや確信が持てません。私は偶然 this old thread 分離されたミラーからZFSプールを回復することについて、そしてそれはゼロの値を持つtxg
への不可解な参照を行います。 detach
でゼロ設定されるuberblockへの参照も他にあります。
まあ、私のbackup
プールへのuberblockはtxg = 0
をリストします(他の場所にあるアクティブなzpoolはこのフィールドにゼロではなく大きな数字を持っています)。また、既存のuberblockは存在しますが、1つしかありません。backup
の他のものは「無効」としてリストされています。残念ながら、オンラインで簡単に入手できるzdb
から出てくるものの多くのドキュメントを見つけることができないようです。
スペアの3番目のドライブが取り外されたことを意味すると思いますか?誰かが私の解釈を確認できますか?ただし、ドライブのデータが他の点では変更されていない場合、そこから回復する方法はありますか? オンラインのいくつかのアドバイス は、切り離されたミラーは再同期化しないと回復できないことを示唆していますが、上でリンクしたスレッドにはSolaris用のコードがあり、ラベルをだましてuberblockに問題がないと思わせるようにかなり単純な関数を実行しているようです。さらに調べてみると、たった3年前の このユーティリティの更新されたSolarisバージョン が見つかりました。
私の理解が正しく、3番目のミラーが切り離されていると仮定すると、Linuxで同様のuberblockラベル修正を試行できますか? Solarisコードを書き直してLinuxに移植する唯一の方法はありますか? (私がそれまでかどうかはわかりません。)
正直なところ、このようなシナリオをオンラインで何度も参照しているので、ZFSに適したデータ回復ツールがないことに驚いています。どうやら 最終的にいくつかのオプションがあります 一般的な問題の基本的なデータ復旧(create
コマンドによって上書きされたプールを復旧する可能性を含む)の場合、これは表示されないようです私にとってはうまくいく可能性があります)が、Solaris用のこの1回限りのスクリプト以外には、切り離されたデバイスを処理するための何も見当たらない。 ZFSプールがインポートに失敗する理由は少なくとも12あり(簡単に回復できる簡単なものの場合もある)、トラブルシューティング、適切なエラーコード、またはドキュメントがほとんどないことを理解するのは非常にイライラします。
再度、どんな助け、考え、または提案もいただければ幸いです。 誰かがこれについてより良い場所を勧めることができたとしても、私はそれを本当に感謝します。
UPDATE2:また、デバイスがoffline
に配置されただけの可能性もあります。私はさまざまなスレッドを読みましたが、オフラインのデバイスは単一のミラーとしてもインポートできなくなる可能性があります。また、メタデータとzdb出力はZFSについて十分に文書化されていないため、何千行ものソースコードを読み取らずに、uberblockとラベルデータの意味を判断する方法がわかりません。
まあ、私は近くにあり、回復への道を見つけたと思います。他からのアドバイスがないので、これまでに学んだことを投稿します。
概要:
labelfix
ユーティリティがあり、インポートできないプールをインポート可能にするために使用できます。create
またはその他のエラーが原因で)、リカバリする特定のプールに接続されているデバイスのみを確認してください。詳細:
Linuxでは、zpoolからオフラインで切り離されたドライブを回復する方法があるようです。ユーザーjjwhitneyが作成した labelfixユーティリティのポート 質問の中で言及したのは、もともとJeff Bonwick(ZFSの発明者)が作成した ほぼ12年前 です。理由がわからないため、このユーティリティはZFSビルドに組み込まれていません。無効なラベルが原因でいくつかの理由でインポートが失敗した場合でも、完全なプールのデータを回復できます。 (この問題についての議論 ここ 。)
(補足:このプロセスで私が気づいたことの1つは、ZFSリカバリツールが大幅に不足していることであり、すべてのデータの完全なバックアップがない限り、何かのためにこのファイルシステムを使用するべきではありませんそして、それがインポート可能であることが確かでない限り、クローゼットに座っているその古いミラードライブが最後のチャンスのバックアップであることに依存しないでください。ZFSは、ZFSが連携しているときにデータの整合性を維持するのに優れていますが、非常に壊れやすいです。それは壊れます-またはあなたが何かマイナーなことをしますが愚かです-あなたのデータはそのままであったとしても、単にすべてアクセスできず、読むことができません)
いずれにしても、labelfixユーティリティは5年間更新されていないため、最新のZFSライブラリファイルでコンパイルできません。幸いにも、私は元のOSバージョンをまだインストールしていて、それを起動して、古い LinuxのZFS ソースtarballをダウンロードし、それを使用して適切なZFSライブラリを取得し、すべての環境でシステムを構築しますまだ動作します。 (私は最新のZFSライブラリで動作するようにlabelfixユーティリティを微調整し始めましたが、現在のコードベースに対応するために修正する必要があるすべての内部について理解していることを考えると、それは少し危険に思われました。古いバージョン。)
そして、すぐにlabelfix
を使用すると、デバイスのラベルをzpool import
少なくとも解釈できます!
これを試す前に、ddrescue
を使用して元のドライブからすべてをコピーしたと言っておきます。そして、私がしたように、ミスをする可能性があるので、私はそれを強くお勧めします。私が誤って書いた元のプールはbackup
という名前だったので、zdb
はさまざまなbackup
プールの複数のバージョンを確認し始め、すべてのメタデータが失敗した理由を理解できませんでした一致。微調整する必要がありましたvdev_validate_skip=1
ZFSカーネルモジュールで、インポートするプールを取得しますが、newerbackup
プールをインポートしました(私が望んだプールではありません)。 import
からのドライブへの正確なパスを指定したにもかかわらず、これが発生したことに注意してください。このメソッドでインポートを強制すると、指定を完全に無視し、デバイスとはまったく異なる構成を使用するように見えましたコマンドにリストされていませんでした。
幸い、ドライブのクローンをもう1つ作成していたので、もう一度実行することができました。ただし、labelfix
もスマートで、現在のドライブ構成を読み取るようです。そのため、最初のbackup
プールから「破損したデータ」を持つ2つの古いドライブがあったという事実に気付きました。残念ながら、この破損により、「修正済み」ラベルはプールをDEGRADED
としてだけでなくFAULTED
としてもリストし、そのためun -import
- ableとしてリストされていました。
この時点で、私はすべての古いドライブを取り外し、システム内でそれらなしで作業するだけで回復の試みが破損しないようにする必要があることに気付きました。残念ながら、labelfix
は1度だけ問題を修正しているようです。そのため、このドライブのクローン#3(現在、最初のバックアップクローンからコピーしています)に進みます。そのクローン作成プロセスが終了したら、他の古いドライブが存在しない状態でlabelfix
を実行します。うまくいけば、DEGRADED
プールを取得してimport
を取得できます。