web-dev-qa-db-ja.com

単一の古いミラーからZFSプールを回復/インポートする

先日、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とラベルデータの意味を判断する方法がわかりません。

6
Athanasius

まあ、私は近くにあり、回復への道を見つけたと思います。他からのアドバイスがないので、これまでに学んだことを投稿します。

概要:

  • 特定の種類の破損した(およびオフライン/デタッチされた)ZFSボリュームのラベルを修正するための、メンテナンスされていない、公式にはサポートされていないlabelfixユーティリティがあり、インポートできないプールをインポート可能にするために使用できます。
  • 何かを行う前に、必ず古いスペアデバイスのクローンを作成し、クローンでのみ作業してください。
  • 同じ名前の2つのプールに関する質問で説明されているような状況がある場合(誤ったcreateまたはその他のエラーが原因で)、リカバリする特定のプールに接続されているデバイスのみを確認してください。
  • また、回復したいプールに関連付けられた可能性があるが、障害が発生しているデバイスをすべて削除します。 (これは、他のプールを完全に破壊し、これらのデバイスの関連付けを解除したと考えている場合にも当てはまります。回復ツールは、古いプールのフラグメントをつなぎ合わせようとし、予期しない方法でデバイスとデータを組み合わせるために古いラベル/ uberblockを読み取ることがあります。)

詳細:

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を取得できます。

2
Athanasius