RAID に mdadm を使用し、ビットロット検出に btrfs を使用して NAS を構築したいと考えています。私のセットアップはかなり基本的なもので、3 つの 1TB ディスクを mdadm で RAID5 に組み合わせ、その上に btrfs を配置しています。
mdadm はビットロスを修復できないことはわかっています。不一致があるかどうかは教えてくれますが、どのデータが正しく、どのデータが不良かはわかりません。ビットロスをシミュレートした後、mdadm に md0 を修復するように指示すると、常にパリティが再構築されます。Btrfs はチェックサムを使用するので、どのデータに不良があるかはわかりますが、パリティが見えないためにデータを修復することはできません。
ただし、btrfs スクラブを実行して syslog を読み取って、チェックサムと一致しなかったデータのオフセットを取得することはできます。次に、md0 のデータ開始オフセット (2048 * 512)、チャンク サイズ (512K)、レイアウト (左対称) がわかっているので、このオフセットをディスクとそのディスク上のオフセットに変換できます。レイアウトとは、最初のレイヤーではパリティが 3 番目のディスクにあり、2 番目のレイヤーでは 2 番目のディスクにあり、3 番目のレイヤーでは最初のディスクにあることを意味します。
このすべてのデータと、ディスク フォーマットに関する btrfs の知識を組み合わせると、どのディスクのどのチャンクに障害があるかを正確に計算できます。ただし、この特定のチャンクを修復するように mdadm に指示する方法が見つかりません。
dd コマンドを使用してパリティと不良チャンクを交換し、mdadm で修復を開始してからそれらを元に戻すスクリプトをすでに作成しましたが、これは良い解決策ではなく、mdadm でこのセクターを不良としてマークし、再び使用しないようにすることを本当に望んでいます。腐敗し始めたので、再び腐敗する可能性が高くなります。
私の質問は次のとおりです:mdadm に単一のチャンク (パリティではない) を修復し、ディスク セクターを不良としてマークするように指示する方法はありますか? 読み取り IO エラーを作成するのでしょうか?
(ZFS はこれらすべてを単独で実行できることは知っていますが、ECC メモリは使いたくありません)
編集:これ質問/回答は、btrfs RAID6 がいかに不安定で、ZFS がいかに安定していて使いやすいかに関するものです。これは、mdadm を使用して単一の既知の障害のあるチャンクを修復する方法についての私の質問には答えていません。
答え1
mdadm にこの特定のチャンクを修復するように指示する方法が見つかりません。
これは、サイレント データ破損がある場合、md にはどのブロックがサイレント破損しているかを知るのに十分な情報がないためです。
ぜひ私の質問4(「md
無効なデータのあるデバイスを使い続けるのはなぜですか?」)の回答はこちらでは、これについてさらに詳しく説明しています。
提案されたレイアウトにとってさらに悪いことに、パリティ ブロックにサイレント データ破損が発生した場合、上位の Btrfs レイヤーではそれを認識できません。 対応するデータ ブロックを持つディスクが故障し、それを交換しようとすると、md は破損したパリティを使用し、データを回復不能に破損します。そのディスクが故障した場合にのみ、Btrfs は破損を認識しますが、その時点ではすでにデータは失われています。
これは、アレイが劣化しない限り、md はパリティ ブロックから読み取らないためです。
では、mdadm に単一のチャンク (パリティではない) を修復し、ディスク セクターを不良としてマークするように指示する方法はありますか? 読み取り IO エラーを作成するのでしょうか?
ハード ドライブ自体が検出した不良セクタについては、不良セクタが md に識別されるため、md は簡単に対処できます。
技術的には で不良セクタを作成できますがhdparm --make-bad-sector
、サイレント データ破損の影響を受けたブロックがどのディスクにあるかをどのように確認するのでしょうか。
次の単純化された例を考えてみましょう。
パリティ式:PARITY = DATA_1 + DATA_2
+--------+--------+--------+
| DATA_1 | DATA_2 | PARITY |
+--------+--------+--------+
| 1 | 1 | 2 | # OK
+--------+--------+--------+
ここで、各ブロックを次の値で静かに破損させてみましょう3
:
+--------+--------+--------+
| DATA_1 | DATA_2 | PARITY |
+--------+--------+--------+
| 3 | 1 | 2 | # Integrity failed – Expected: PARITY = 4
| 1 | 3 | 2 | # Integrity failed – Expected: PARITY = 4
| 1 | 1 | 3 | # Integrity failed – Expected: PARITY = 2
+--------+--------+--------+
最初のテーブルを調べなければ、どのブロックが破損しているかをどうやって知るのでしょうか?
確実に知ることはできません。
このため、Btrfs と ZFS は両方ともチェックサム ブロックを使用します。ディスク領域は少し多く必要になりますが、この追加情報により、ストレージ システムはどのブロックがあるのかを判断できます。
からJeff Bonwick のブログ記事「RAID-Z」:
RAID-Z ブロックを読み取るたびに、ZFS はそれをチェックサムと比較します。データ ディスクが正しい答えを返さなかった場合、ZFS はパリティを読み取り、どのディスクが不良データを返したかを判断するために組み合わせ再構築を実行します。
md 上の Btrfs でこれを行うには、Btrfs でチェックサムが一致するまで各ブロックを再計算する必要がありますが、これは時間のかかるプロセスであり、ユーザー/スクリプトに公開される簡単なインターフェイスはありません。
ZFSはこれらすべてを単独で実行できることは知っていますが、ECCメモリは使いたくありません
ZFS も Btrfs over md も ECC メモリに依存しておらず、ECC メモリを認識しません。ECC メモリはメモリ内のサイレントなデータ破損のみをキャッチするため、ストレージ システムに依存しません。
私は以前、RAID-5とRAID-6(それぞれZFS RAID-ZとRAID-Z2に類似)ではBtrfsよりもZFSを推奨しました。mdadm raid6 上の Btrfs?そしてATA が応答しなくなったときに md RAID のデバイスが故障するしかし、この機会に ZFS の利点をさらにいくつか概説したいと思います。
- ZFS がサイレントデータ破損を検出すると、人間の介入なしにその場で自動的に即座に修正されます。
- ディスク全体を再構築する必要がある場合、ZFS はブロックデバイス全体を不必要に実行するのではなく、実際のデータのみを「再同期」します。
- ZFS は論理ボリュームとファイルシステムに対するオールインワン ソリューションであり、md 上の Btrfs よりも管理が複雑ではありません。
- RAID-ZとRAID-Z2は、
- md RAID-5/RAID-6上のBtrfsは、サイレントに破損したデータブロックのエラー検出のみを提供し(さらに、サイレントに破損したパリティブロックは手遅れになるまで検出されない可能性があります)、エラー訂正を簡単に行う方法はありません。
- Btrfs RAID-5/RAID-6は、「複数の深刻なデータ損失バグがある「」。
- ZFS RAID-Z2でディスク全体を静かに破損した場合、データはまったく失われませんが、md RAID-6では、実際には455,681個のiノードが失われました。
答え2
mdadm の読み取りエラーを作成する方法を見つけました。
dmsetup を使用すると、テーブルから論理デバイスを作成できます。
デバイスは、各セクター(512バイト)のターゲットを指定するテーブルをロードすることによって作成されます。
から:マニュアルページ
これらのテーブルでは、IO エラーを返すオフセットを指定できます。例:
0 4096 linear /dev/sdb 0
4096 1 error
4097 2093055 linear /dev/sdb 4097
これにより、オフセット 4096*512 にエラーがあるデバイス (1GB) が作成されます。