btrfsの送受信が正常かどうかを確認するには?

btrfsの送受信が正常かどうかを確認するには?

btrfs sendテラバイト規模のデータを転送するために使用できますが、receiveこれらのコマンドは有用な進行出力を生成しません(使用されている場合でも-v)。成功を確認するには?

たとえば、という名前の新しいサブボリュームを作成する場合は、source1GBのランダムデータを書き込んで転送できるように、読み取り専用に設定します。

# btrfs subvolume create source
# head -c 1G < /dev/urandom > source/data
# btrfs property set source ro true

btrfs sendその後、新しいサブボリュームのコピーを使用して作成しますが、receive完了する前にプロセスを中止します。

# mkdir destination
# btrfs send source | btrfs receive destination
At subvol source
At subvol source
^C

btrfs subvolume list問題がないことを示します。

# btrfs subvolume list .
ID 1216 gen 370739 top level 5 path source
ID 1219 gen 371244 top level 5 path destination/source

新しいサブボリュームは正常に移動できますが、そのデータは明らかに破損しています。

# exa -lT
   - ├── destination
   - │  └── source
251M │     └── random_data
   - └── source
1.1G    └── random_data

btrfs subvolume show destination/sourceサブボリュームが不完全であるという警告は表示されません。これはsがsと等しくないことを示し、destination/source実行が完了した場合にのみsがsに設定されているようです。UUIDsourcedestination/sourceReceived UUIDsourceUUIDbtrfs receive

Received UUID作成されたサブボリュームが、btrfs receive別のファイルシステム上の対応するUUIDを持つサブボリュームの変更されていない完全コピーであることは保証されますか?

この部分man btrfs-senddestination/sourceそうしないことをお勧めします。上記の例では、将来のスナップショットの親スナップショットを使用すると、損傷を検出してsource回復できない可能性があることを示唆しているようです。しかし、このアドバイスの目的send -cとこのアドバイスがsend -p

増分モード(オプション-pおよび-c)では、送信者と受信者の両方が使用できる以前に送信されたスナップショットを使用して、送信されたスナップショットを他のファイルシステムで再構成するために送信する必要がある情報の量を減らすことができます。

-p <parent>与えられたら、このオプションを省略できます。-c <clone-src>この場合、btrfs sendはレプリケーションソースから適切な親エントリを決定します。

これらのスナップショットが両方(送信者と受信者)の両方でまったく同じ状態にあることを保証しない限り、複製ソースを指定することはできません。

私が知る限り、snap-syncbuttersinkその他の同様のツールは、出力をbtrfs send一連のファイルにリダイレクトし、信頼できる方法(rsync単純パイプではなく)を使用して送信することによってこの問題を解決します。ディストリビューションに含まれていないサードパーティ製ソフトウェアに依存せずに自己増分バックアップソリューションを開発する場合、これは正しいアプローチですか?

答え1

Received UUID重要な要約:このフラグが設定されていると、readonly不注意や悪意が介入されない限り、問題が発生する可能性はありません。

@timakroがすでに答えで述べたように、Received UUIDこの転送が完了するまで設定されません。フラグも同じですreadonly。これは、ストリーム内のすべてのコマンドがチェックサム処理されるという事実と組み合わせて(私が知っている限り、送信されたメタデータにもチェックサムが含まれている)、受信側で破損したスナップショットで終わる可能性が低くなりますreadonlyReceived UUID。これらのいずれかが設定されていない場合、btrfsは将来の参照のためにそのスナップショットの使用を拒否しますbtrfs receive

特別に作成されたストリームを受信した場合、または一部のプロセスまたはユーザーが受信したスナップショットを受信して​​いる間にその内容を変更すると、意図的な損傷が発生する可能性があります。btrfs-receiveマンページから:

間違い

btrfs receive が正常に完了すると、サブボリュームを読み取り専用に設定します。ただし、受信プロセス中に、受信パスのファイルまたはディレクトリへの書き込み権限を持つユーザーは、ファイルを追加、削除、または変更できます。この場合、結果の読み取り専用サブボリュームは、トランスポートサブボリュームの正確なコピーではありません。

正確なコピーを作成することが目的の場合は、受信操作が完了し、サブボリュームが読み取り専用に設定されるまで、受信パスをユーザーアクセスから保護する必要があります。

さらに、現在の受信は、デルタトランスポートストリームが実際に意味があるかどうかを確認する操作を正しく実行していないため、特別に作成されたトランスポートストリームは、同じファイルシステム上の任意のファイルへの参照リンクを含むサブボリュームを作成できます。したがって、ユーザーは信頼できないソースからのトランスポートストリームにbtrfs受信を使用しないでください。信頼できないネットワークを介して信頼できるストリームを送信するときに信頼できるストリームを保護することをお勧めします。

readonlyまた、サブボリュームのフラグを無効にし、内容を変更してから再度有効にできることにも注意する価値があります。どちらにしても、すべての保証はなくなります。

出力をファイルにパイプしてファイルを転送するいいえ上記の保護のいずれかを提供してください。個人的にのbtrfs send出力をssh。ストリームをファイルに途中で保存すると、信頼できない接続によって中断された転送を再開できるという利点があります。いいえデータの整合性の形式では、いかなる保証も提供されません。

受信したスナップショットが送信されたスナップショットと一致することを確認するための良い(完璧ではありませんが)方法は、を使用することですrsync -avcn --del path/to/sent/snapshot/ user@remote:path/to/received/snapshot/

答え2

私はあなたが言った最後の部分だけに基づいて12以上のバックアップシステムを持っています。 1TBを超えるネットワークバックアップを処理しているため、直接パイプはオプションではありませんでした。少しの損失と時間の無駄を取ることはできません。

私の最終設定は次のとおりです。

ブートステップ:

  1. 最初のフルスナップショットを撮る
  2. スナップショットをローカルファイルに送信する(-fオプション)
  3. 再同期または物理メディア転送スナップショットファイルをリモートサイトに転送します。
  4. 最初のスナップショットをリモートで受信

増分ステップ:

  1. 新しいローカルスナップショット

  2. 現在のスナップショットと前のスナップショットの間のdiffファイルをローカルに作成して転送します。

  3. リモートサイトへの再同期

  4. 転送されたスナップショットファイルをリモートにインポートする

  5. クリーンアップロジック(古いスナップショットの維持、削除の考慮...)

このプロジェクトは3年間行われてきました。最悪の場合、スナップショットが一致しない場合、最後の2つ(ローカル1つ、リモート1つ)を削除すると、次の転送で再び機能します。

幸運を祈る

答え3

Received UUID作成されたサブボリュームが、btrfs receive別のファイルシステム上の対応するUUIDを持つサブボリュームの変更されていない完全コピーであることは保証されますか?

このReceived UUIDフィールドはサブボリュームを受信した後にのみ設定されます。 ~からbtrfs-progs ソース:

@received_uuid:このサブボリュームが受信したサブボリュームのUUID、またはこのサブボリュームが受信されていない場合はすべて0です。このフィールド@stransid、@rtransid、@stime、および@rtimeは、サブボリュームを受信した後にユーザースペースによって手動で設定されます。

詳細情報表示モードでも確認できます。

$ btrfs send -v 2020-12-28/ | ssh root@link "btrfs receive -v /mnt/test"
At subvol 2020-12-28/
BTRFS_IOC_SEND returned 0
joining genl thread
At subvol 2020-12-28
receiving subvol 2020-12-28 uuid=778ec7aa-6709-d240-b41d-58d99a6fb9a0, stransid=9
BTRFS_IOC_SET_RECEIVED_SUBVOL uuid=778ec7aa-6709-d240-b41d-58d99a6fb9a0, stransid=9

答え4

@timakroのケースをテストしましたが、うまくいきません。完全に転送されていないスナップショットにはまだUUIDがあります。

まず、別々にマウントされた2つのbtrfsボリュームがあります。

➜  lsblk|grep loop99
loop99       7:99   0     1G  0 loop 
|-loop99p1 259:0    0   512M  0 part /mnt/tmp1
`-loop99p2 259:1    0   486M  0 part /mnt/tmp2

次に、最初のbtrfsボリュームに新しいサブボリュームを作成し、そのサブボリュームにランダムなファイルを作成しました。

➜  sudo btrfs subvolume create tmp1/ori
Create subvolume 'tmp1/ori'
➜  sudo dd if=/dev/urandom of=tmp1/ori/test.iso bs=1M count=256
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 1.58701 s, 161.3 MB/s

読み取り専用スナップショットを作成したら、それを2番目のbtrfsボリュームに転送して転送を中止します。

➜  sudo btrfs subvolume snapshot -r tmp1/ori tmp1/snap         
Create a readonly snapshot of 'tmp1/ori' in 'tmp1/snap'
➜  sudo btrfs send tmp1/snap | sudo btrfs receive tmp2 
At subvol tmp1/snap
At subvol snap
^C

ハッシュを介して受信したスナップショットは元のものとは異なり、これは破損していることを意味します。

➜  sudo sha256sum tmp1/snap/test.iso                
49455edf92d582346215679a52eb6d72f0afa10748ef62f1ce3fc5e417e70f6a  tmp1/snap/test.iso
➜  sudo sha256sum tmp2/snap/test.iso
bb30f487a39579dabc768129d59d4abeca25777e4eeb4f41b9beca366d379bab  tmp2/snap/test.iso

それではUUIDをチェックしてみましょう。

➜  sudo btrfs subvolume list tmp1 -u
ID 257 gen 25 top level 5 uuid b5f8ff5d-fafb-814a-a31b-25bb96c185b5 path ori
ID 258 gen 25 top level 5 uuid d2bfa408-b330-954f-9aa8-138de5030898 path snap
➜ sudo btrfs subvolume list tmp2 -u
ID 256 gen 31 top level 5 uuid 77950b38-812d-3646-88cd-8107def1eced path snap

不完全なスナップショットには独自のUUIDがあり、読み取り専用フラグが設定されていないことに加えて、不完全な状態を示す表示やヒントはありません。

関連情報