第23章 ファイルのスプリットブレインの手動リカバリー

本章では、スプリットブレインから手動でリカバリーする手順を説明します。
  1. 以下のコマンドを実行して、スプリットブレインにあるファイルのパスを取得します。
    # gluster volume heal VOLNAME info split-brain
    コマンド出力から、クライアントから実行したファイル操作が Input/Output エラーで失敗したファイルを特定します。
  2. マウントポイントからスプリットブレインファイルを開くアプリケーションを閉じます。仮想マシンを使用している場合は、マシンの電源をオフにする必要があります。
  3. getfattr コマンドを使用して、ファイルの AFR changelog 拡張属性を取得して検証します。次に、スプリットブレインのタイプを特定し、ファイルの 'good copy' が含まれるブリックを決定します。
    getfattr -d -m . -e hex <file-path-on-brick>
    以下に例を示します。
    # getfattr -d -e hex -m. brick-a/file.txt
    #file: brick-a/file.txt
    security.selinux=0x726f6f743a6f626a6563745f723a66696c655f743a733000
    trusted.afr.vol-client-2=0x000000000000000000000000
    trusted.afr.vol-client-3=0x000000000200000000000000
    trusted.gfid=0x307a5c9efddd4e7c96e94fd4bcdcbd1b
    trusted.afr.VOLNAMEvolname-client-<subvolume-index> を持つ拡張属性は、ファイルの changelog を維持するために AFR によって使用されます。trusted.afr.VOLNAMEvolname-client-<subvolume-index> の値は、glusterFS クライアント (FUSE または NFS-server) プロセスにより計算されます。glusterFS クライアントがファイルまたはディレクトリーを変更すると、クライアントは各ブリックに問い合わせ、ブリックのレスポンスに従って changelog 拡張属性を更新します。
    subvolume-indexgluster volume info VOLNAMEbrick number - 1 です。
    以下に例を示します。
    # gluster volume info vol
    Volume Name: vol
    Type: Distributed-Replicate
    Volume ID: 4f2d7849-fbd6-40a2-b346-d13420978a01
    Status: Created
    Number of Bricks: 4 x 2 = 8
    Transport-type: tcp
    Bricks:
    brick1: server1:/rhgs/brick1
    brick2: server1:/rhgs/brick2
    brick3: server1:/rhgs/brick3
    brick4: server1:/rhgs/brick4
    brick5: server1:/rhgs/brick5
    brick6: server1:/rhgs/brick6
    brick7: server1:/rhgs/brick7
    brick8: server1:/rhgs/brick8
    上記の例では、以下のようになります。
    Brick             |    Replica set        |    Brick subvolume index
    ----------------------------------------------------------------------------
    /rhgs/brick1     |       0               |       0
    /rhgs/brick2     |       0               |       1
    /rhgs/brick3     |       1               |       2
    /rhgs/brick4     |       1               |       3
    /rhgs/brick5     |       2               |       4
    /rhgs/brick6     |       2               |       5
    /rhgs/brick7     |       3               |       6
    /rhgs/brick8     |       3               |       7
    ```
    ブリック内の各ファイルは、それ自体の変更ログと、そのブリックがレプリカセット内の他のすべてのブリックに存在するファイルを維持します。
    上記の例のボリュームでは、brick-a のすべてのファイルにはエントリーが 2 つ、それ自体には、そのレプリカペアにあるファイルのもう 1 つがエントリーになります。以下は、brick2 の changelog です。
    • trusted.afr.vol-client-0=0x000000000000000000000000 - is the changelog for itself (brick1)
    • trusted.afr.vol-client-1=0x000000000000000000000000 - changelog for brick2 as seen by brick1
    同様に、brick2 のすべてのファイルは以下のようになります。
    • trusted.afr.vol-client-0=0x000000000000000000000000 - changelog for brick1 as seen by brick2
    • trusted.afr.vol-client-1=0x000000000000000000000000 - changelog for itself (brick2)
    注記
    このファイルは、レプリカの他のブリックにのみエントリーを持ちません。たとえば、brick1 には trusted.afr.vol-client-1 が設定され、brick2 には trusted.afr.vol-client-0 だけが設定されます。changelog の解釈は、以下の説明と同じです。
    他のレプリカのペアでも同じ拡張が可能です。

    changelog (保留中の操作数) 値を解釈

    各拡張属性には、24 進数の 16 進数の値があります。最初の 8 桁はデータの変更ログを表します。2 番目の 8 桁はメタデータの変更ログを表します。最後の 8 桁はディレクトリーエントリーの変更ログを表します。

    同じ語を表す Pictally は以下の通りです。
    0x 000003d7 00000001 00000000110
            |      |       |
            |      |        \_ changelog of directory entries
            |       \_ changelog of metadata
             \ _ changelog of data
    ディレクトリーの場合は、メタデータおよびエントリー変更ログは有効です。通常のファイルでは、データおよびメタデータの changelogs が有効となります。デバイスファイルなどの特別なファイルの場合は、メタデータの変更ログが有効になります。ファイルのスプリットブレインが発生すると、データスプリットブレインまたはメタデータスプリットブレインのいずれかになります。
    以下は、同じファイルにあるメタデータのスプリットブレインの例です。
    # getfattr -d -m . -e hex /rhgs/brick?/a
    getfattr: Removing leading '/' from absolute path names
    #file: rhgs/brick1/a
    trusted.afr.vol-client-0=0x000000000000000000000000
    trusted.afr.vol-client-1=0x000003d70000000100000000
    trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57
    #file: rhgs/brick2/a
    trusted.afr.vol-client-0=0x000003b00000000100000000
    trusted.afr.vol-client-1=0x000000000000000000000000
    trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57

    changelogs のスクラッチ

    ファイル /rhgs/brick1/a の changelog 拡張属性は以下のとおりです。
    • trusted.afr.vol-client-0 are all zeros (0x00000000................) の最初の 8 桁
      trusted.afr.vol-client-1 の最初の 8 桁は、すべてのゼロ (0x000003d7................) ではありません。
      そのため、/rhgs/brick-a/a の changelog は、一部のデータ操作が、/rhgs/brick2/a で失敗したことを示します。
    • trusted.afr.vol-client-0 are all zeros (0x........00000000........) の 2 番目の 8 桁と、trusted.afr.vol-client-1 の 2 番目の 8 桁がすべてゼロ (0x........00000001........) ではありません。
      そのため、/rhgs/brick1/a の changelog は、一部のデータ操作が、/rhgs/brick2/a で失敗したことを示します。
    ファイル /rhgs/brick2/a の changelog 拡張属性は以下のとおりです。
    • 最初の 8 桁の trusted.afr.vol-client-0 は、すべてのゼロ(0x000003b0................)ではありません。
      trusted.afr.vol-client-1 の最初の 8 桁はすべて 0x00000000................ です。
      そのため、/rhgs/brick2/a の changelog は、一部のデータ操作が、/rhgs/brick1/a で失敗したことを示します。
    • trusted.afr.vol-client-0 の 2 番目の 8 桁は、ゼロ(0x........00000001........)
      trusted.afr.vol-client-1 の 2 番目の 8 桁はすべてゼロ(0x........00000000........)です。
      そのため、/rhgs/brick2/a の changelog は、一部のデータ操作が、/rhgs/brick1/a で失敗したことを示します。
    ここでは、両方のコピーには、他のファイル上にないデータ、メタデータの変更があります。したがって、これはデータとメタデータのスプリットブレインです。

    正しいコピーの決定

    ファイルの stat および getfattr の出力を検査して、保持するメタデータとファイルの内容を決定し、保持するデータを決定する必要があります。上記の例を続けるために、ここでは /rhgs/brick1/a のデータと /rhgs/brick2/a のメタデータを保持しています。

    スプリットブレインを解決するための関連する changelogs のリセット

    データスプリットブレインの解決

    ファイルの changelog 拡張属性を、/rhgs/brick1/a で成功しているが /rhgs/brick-b/a で失敗したかのようにファイルを変更する必要があります。ただし、/rhgs/brick2/a には、/rhgs/brick2/a でデータ操作が成功したことを示す changelog はありませんが、/rhgs/brick1/a で失敗します。/rhgs/brick2/atrusted.afr.vol-client-0 で changelog のデータ部分をリセットする必要があります。

    メタデータのスプリットブレインの解決

    ファイルの変更ログ拡張属性は、/rhgs/brick2/a で成功したものの、/rhgs/brick1/a で失敗したかのように、ファイルの changelog 拡張属性を変更する必要があります。ただし、/rhgs/brick1/a には、一部のメタデータ操作が /rhgs/brick1/a で成功しても /rhgs /brick2/a で失敗したことを示す changelog を含めることはできません/rhgs/brick1/atrusted.afr.vol-client-1 の changelog のメタデータ部分をリセットする必要があります。
    以下のコマンドを実行して、拡張属性をリセットします。
    1. trusted.afr.vol-client-0 0x000003b00000000100000000 から 0x000000000000000100000000 にするには、/rhgs/brick2/a で以下のコマンドを実行します。
      # setfattr -n trusted.afr.vol-client-0 -v 0x000000000000000100000000 /rhgs/brick2/a
    2. trusted.afr.vol-client-1 0x0000000000000000ffffffff から 0x000003d70000000000000000 にするには、/rhgs/brick1/a で以下のコマンドを実行します。
      # setfattr -n trusted.afr.vol-client-1 -v 0x000003d70000000000000000 /rhgs/brick1/a
    拡張属性をリセットすると、changelogs は以下のようになります。
    # getfattr -d -m . -e hex /rhgs/brick?/a
    getfattr: Removing leading '/' from absolute path names
    #file: rhgs/brick1/a
    trusted.afr.vol-client-0=0x000000000000000000000000
    trusted.afr.vol-client-1=0x000003d70000000000000000
    trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57
    
    #file: rhgs/brick2/a
    trusted.afr.vol-client-0=0x000000000000000100000000
    trusted.afr.vol-client-1=0x000000000000000000000000
    trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57
    

    ディレクトリーエントリーのスプリットブレインの解決

    AFR には、ディレクトリーにスプリットブレインがある場合に、ディレクトリーに異なるエントリーを一貫してマージする機能があります。1 つのブリックディレクトリー storage にエントリー 12 があり、他のブリックに 34 のエントリーがある場合、AFR はディレクトリー内の全エントリーをマージして、同じディレクトリーに 1, 2, 3, 4 エントリーを追加します。ただし、ディレクトリーのファイルが削除されたためスプリットブレインが発生した場合は、ファイルが再び削除される可能性があります。スプリットブレインの解決では、ファイル名が同じエントリーがあり、そのディレクトリーに gfid が異なるエントリーが 1 つ以上ある場合、人間の介入が必要になります。

    以下に例を示します。
    brick-a では、ディレクトリーには、gfid_x を持つfile1と、file2の2つのエントリーがあります。brick-b では、ディレクトリーには、gfid_y を持つfile1file3 の 2 つのエントリーがあります。ここでは、ブリック上の file1 の gfid は異なります。このようなディレクトリーのスプリットブレインには、問題の解決に人間の介入が必要です。スプリットブレインを解消するためには、brick-afile1brick-bfile1を削除する必要があります。
    さらに、対応する gfid-link ファイルを削除する必要があります。gfid-link ファイルは、ブリックのトップレベルディレクトリーにある .glusterfs ディレクトリーにあります。ファイルの gfid が 0x307a5c9efddd4e7c96e94fd4bcdcbd1b (get fattr コマンドから受信した trusted.gfid 拡張属性)の場合、gfid-link ファイルは /rhgs/brick1/.glusterfs/30/7a/307a5c9efddd4e7c96e94fd4bcdcbd1b にあります。
    警告
    gfiid-link を削除する前に、そのブリックに存在するファイルへのハードリンクがないことを確認する必要があります。ハードリンクが存在する場合は、それらを削除する必要があります。
  4. 以下のコマンドを実行して自己修復をトリガーします。
    # ls -l <file-path-on-gluster-mount>
    または
    # gluster volume heal VOLNAME