linux

mdadm RAID10(ディスク4本)をRAID5へ移行する方法。

私はDebian BusterでLinuxのmdadmをベースにしたソフトウェアRAID10を使用しています。元々、RAID10は最高のパフォーマンスを持っていることが分かっていました。しかし、私はより多くのスペースが必要で、+50%のスペースと交換するために、書き込みパフォーマンスを受け入れることにしました。

# 猫 /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4]
md1 : active raid10 sdd1[5] sda1[4] sdb1[1] sdc1[2]
      3899738112 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU]
      bitmap: 3/30 pages [12KB], 65536KB chunk

unused devices: <none>

このストレージはNFS経由で提供されており、理想的にはダウンタイムなしにRAIDを変換することができます。確かにバックアップは取ってありますし、障害は致命的なものではありませんが、もしうまくいくのであれば、中断することなく移行するのはいかがなものでしょう。


このプロセスを説明している 2012 年の記事を見つけました。コマンドは非常に正しいことが判明しました。当時、著者は mdadm ユーティリティ (またはおそらくカーネル ドライバー) が最初のコマンドでシステムをすぐにハングさせるという問題を抱えていました。この問題はその後修正されたようです。

https://www.tummy.com/blogs/2012/03/29/changing-a-raid-10-into-a-raid-5/

mdadmにはRAID10→RAID5という直接的なパスがありません。その代わり、最初にRAID0にデグレードする必要があります。

# mdadm --grow /dev/md1 --level=0 --raid-devices=2
mdadm: /dev/md1: could not set level to raid0

これはすぐに有効になり、2 つのデバイスが故障し、アレイから削除されました。残念ながら、RAID レベルは RAID0 に設定されていませんでした。 dmesg が示した:

md/raid0:md1: All mirrors must be already degraded!
md: md1: raid0 would not accept array

問題は、 sysfs がアレイが劣化していないと報告したことであることがわかりましたが、実際には劣化していて、 mdadmcat /proc/mdstat は正しく表示されていました。

# cat /sys/block/md1/md/degraded
0

NFSサーバーを停止し、ファイルシステムをアンマウントし、LUKSデバイスを閉じ、RAIDアレイを停止し、RAIDアレイを再組み立てし、すべてのサービスを再起動する以外に、これを修正する方法は見つかりませんでした。その後、それは正しくデグレードとして報告され、RAID0に変換することができました。

そうすれば、RAID5で4台まで増やせますからね。

# mdadm --grow /dev/md1 --level=5 --raid-devices=5 --add /dev/sdb1 /dev/sdd1

これまでとは異なり、 cat /proc/mdstat は進行中の「再構築」ではなく「再形成」を示しました。これにはかなりの時間がかかり (約 10 時間)、システムの応答は RAID10 の再構築時よりもはるかに遅くなりました。再構築の時間のためにそのままにしておきました。

リシェイプが完了したため、RAID5はきれいになり、速度も良好です。おそらく測定時に間違えたのでしょうが、読み込み速度は以前記録したものよりも速くなり、書き込み速度も私にとっては許容範囲内です。

# 猫 /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] 
md1 : active raid5 sdd1[5] sdb1[3] sda1[4] sdc1[7]
      5849607168 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]

unused devices: <none>

(免責事項: 移行が既に完了しているときに、すべてのストーリーを書き留めました。実際のコマンドとエラー メッセージを注意深く説明しようとしましたが、小さな間違いがあるかもしれません。全体的なプロセスは説明どおりに機能しました。)




(まだ)テストされていません(重要なデータを以下の手順に信頼しないでください)が、ここでは、使用可能なスペースが増加し、 mdadm --grow が「RAID10 レイアウトが拡張操作には複雑すぎる」と言うシナリオのアイデアを示します。

  1. mdを停止する
  2. mdの各パーティションの最初の数MiBをバックアップする(RAIDのスーパーブロックが各パーティションの先頭付近にあると仮定する)
  3. スーパーブロックの拭き取り
  4. パーティションを使用して --assume-clean で RAID5 (または他の RAID) を作成します
  5. MD の各パーティションのスナップショットを作成します。たとえば、https ://gist.github.com/jowagner/b36024636140ddf453c12eaf6e590b5d に従ってください
  6. 手順2のバックアップをパーティションのスナップショットにリストアする
  7. スナップショットからRAID10を組み立てる
  8. dd から RAID5 にすべてのデータを追加します。2 つのストライプ サイズの最小公倍数を使用するとパフォーマンスが向上する可能性がありますが、任意のブロック サイズを使用する必要があります。最初の数回の読み取りは、ステップ 5 で書き込まれたコピー オン ライト データに由来するため、書き込みによって破損することはありません。このアイデアは、使用可能なスペースが増加するシナリオに限定されます)。
  9. RAID10を停止する
  10. スナップショットを破棄する

これは、スナップショットへの書き込みをCOWデバイスにリダイレクトするだけで、オリジンデバイスへの書き込みがCOWデバイスに保存される古いデータのコピーをトリガーしないことを前提としています(さもなければ、余分なスペースが必要となり、この解決策は実用的ではありません)。

さらに、旧RAIDのスーパーブロックが各パーティションの末尾にある場合、これらのデータもステップ3の前にバックアップする必要があります。シークする適切な位置とデータ量を計算します。私はPythonを数行使いましたが、おそらくコマンドラインツールで可能でしょう。