wiki:LinuxRAID1Recovering

LinuxのソフトウェアRAIDで助かった!

 id:kazushi_nakamura氏といっしょに個人的に運用しているサーバ(メールとウェブとDNS)のディスクが壊れたのです。 ディスクが壊れても真っ青になったり、喪失感に襲われて腑抜けになったりもしていないのは、まさにRAID1のおかげでした。 実はね、年末の28日あたりに/dev/sdbがすっとんで、その旨の警告メールが届いていたのです。 ところが僕のかしこいスパムフィルタは、その短くて素っ気ないメールを「迷惑メール?」フォルダに分類してやがりました。 はい。ごめんなさい。ホワイトリスト、がんばってデプロイしますです。 メールに気づいたのが正月明けて2日。 ディスクの交換が終わって定常運転に戻ったのが先ほど、4日の夜でした。 その間、RAID1なのにドライブ1台で動いていたのです。恐い恐い。 同時期に購入したドライブ2台なので、同時期に壊れる可能性を心配しなきゃいけない。 ただ、いずれにしても、1台壊れても無事でいられたのはRAID1のおかげでした。 もちろん毎日バックアップを取っているけれど、メールが一日分消えてしまうのは耐えられません。 RAIDじゃなかったら、悲しい気持ちでいっぱいに成っていたはずです。

せっかくなので、修復の手順を記録しておきましょう。

前提の状況

  • OSは、Linux Debian 4.0 (Etch)。
  • 1Uサーバ。ドライブのホットスワップはできない構造。
  • 250GBのSATAドライブ2台を内蔵。
  • それぞれから240GBのパーティションを切り出し、
  • LinuxのソフトウェアRAIDで、RAID1を構成してあった。
  • 余ったパーティションは、スワップとして使っていた。
  • sdb(2個目のドライブ)が故障。セクタのエラーではなく、認識さえできない状態。

だめな手順

まず、修復の手順を検討しました。普通に考えたら、以下の手順を取るでしょう。 ホットスワップはできないのです。

  1. シャットダウンして電源を落とす。
  2. 壊れたドライブを取り替える。
  3. 起動する。
  4. 新しいドライブをRAIDに参加させる。
  5. リビルドさせて放っておく。

でも、この手順はとれません。なぜならば、電源を落としたことでもう一台のドライブまで故障してしまう可能性があります。 そもそも、よく言われるのが、連続稼働のマシンを落とすとドライブが壊れることが多いってことです。 その上、今の状況は、ドライブのうち一台がうんともすんとも言わない程にすっとんでいて、同時期に購入したもう一台にも危険があるかも知れないのです。 先に電源を落とすわけにはいきません。

解決策

さて。解決策がありました。LinuxのソフトウェアRAIDで良かったなあって思います。

  1. SATAドライブ-USBアダプタを調達する。
  2. 新しいドライブを調達。現在のドライブよりも大きければ何でもいい。
  3. 新しいドライブをアダプタに接続し、サーバにUSBで接続する。
  4. fdiskで、既存のRAID参加パーティションと同じサイズのパーティションを切り出す。
  5. 壊れたドライブのパーティションをRAIDから削除。
  6. 新しいドライブのパーティションをRAIDに参加させる。
  7. 勝手にリビルドが始まるので、終わるまでじっと待つ。
  8. マシンをシャットダウン。
  9. SATAドライブ-USBアダプタを取り外し、新しいドライブも取り外す。
  10. 壊れたドライブを、新しいドライブに交換する。
  11. マシンを起動。
  12. 新しいドライブにGRUBをインストールする

キモは、LinuxのソフトウェアRAIDなら、SATAやらUSBやらとバスが異なるドライブを混在できるっていうことです。 ソフトウェアRAIDでよかった!

5.と6.は、「mdadm /dev/md0 --remove /dev/sdb1」とか「mdadm /dev/md0 --add /dev/sdd1」って感じ。 難しい話はありません。

7.は、「mdadm --detail /dev/md0」か「cat /proc/mdstat」でわかります。 後者の方が、進捗具合や処理速度がわかっていいです。 特に近年の大容量ドライブだと処理が遅くてたまらないので、カーネルパラメータを調整します。/proc/sys/dev/raid/」に「speed_limit_max」と「speed_limit_min」という(偽)ファイルがあります。 LinuxのソフトウェアRAIDでは、RAIDのリビルドはマシンがヒマなときに行います。 これは、通常業務に影響を与えないためです。 ただし、ヒマじゃなくても最低限「speed_limit_min」の速度では処理を行います。 また、どんなにヒマでCPUとI/Oが余っていても、「speed_limit_max」より高速には処理しません。 いずれの値もKB/sです。 このうち、「speed_limit_min」の値が小さすぎるのです。 デフォルトでは1000KB/s。たかだか8Mbpsに過ぎません。 マシンが忙しければ、240GBで三日三晩かかっても文句は言えないわけです。 「speed_limit_min」を変更しましょう。 リビルドが進行している途中であっても、このパラメータの変更は即座に反映されます。 今回は最低50MB/sを指示しました。

echo 50000 > /proc/sys/dev/raid/speed_limit_min

とはいえ、USBやらドライブやらの性能のせいで、25MB/s程度にしか成りませんでした。240GBで3時間くらいかかりました。

10.について。 USB経由でビルドしたRAIDと、直接にSATAのポートに接続したRAIDとで整合性はあるのか、フォーマットは同じなのかと心配する向きもあるかもしれません。 結論から言えば、大丈夫。考えてみればあたりまえですね。 よく、ウィンドウズで使ってて壊れたドライブを、USBでLinuxマシンにつなげてメンテしたりしますよね??  え、しませんか?

  1. について。

USBに接続されている状態で書き込めばいいと思いがちですが、一旦起動させてディスクの認識順序を確認するほうが良いとアドバイスを頂きました。 細かいことを悩まない方法も検討しておきたいです。 --akitoshi

ブートローダ(GRUB)のインストールについては、「最小限のダウンタイムでRAIDに移行する」ページの最後のあたりを参照してください。 壊れたのが1台目(sda)なのか2台目(sdb)なのかによっても戦略が少し異なります。 2台目が壊れた場合は普通に1台目から起動できるはずなので、僕だったら2台目へのブートローダの書き込みは立ち上げてから焦らずじっくりやります。 ダウンタイムは最小限にしたい。 1台目が壊れた場合は、BIOSが2台目にフォールバックしてくれればいいのですが、そうしてくれなくて起動できない可能性があります。 そのため、僕だったら、USBに接続されている状態で、7.のあたりで書き込みます。BIOSによる認識順序は気にしません。 なぜならば、「最小限のダウンタイムでRAIDに移行する」で書いたとおり、1台目から起動されようが、2台目から起動されようが、Linuxカーネルが立ち上がってRAIDが認識されるまでは起動されたドライブ内だけが参照されるからです。 もちろん、よくよく考えると、これでも起動できなくなる可能性が依然として残っています。 でも、そもそもこれは現状で最も一般的に使用されているバージョンのGRUB(0.97あたり)がRAIDの都合を考えてくれないのが原因なので、これは諦めるのが賢明でしょう。最新のバージョンではRAIDを正式にサポートしているらしいですが、これを採用したディストリビューションを僕は知りません。 もちろん、これら作業を行うときは、GRUB入り起動CDかGRUB入りUSBメモリを手元に用意しておくのがいいです。 逆に、GRUB入りのCDまたはUSBメモリがあれば、11.での起動で失敗しても恐れることはありません。 むしろ、Linux RAIDなシステムでは、ハードディスク上のブートローダに頼らず、GRUB入りのCDまたはUSBメモリを常にマシンに入れておくという戦略の方が安全かもしれませんよ。(2009/4/3 - sgk)

まとめ

キーポイントのまとめと、ここでは書かなかったこと。

  • LinuxのソフトウェアRAIDはすばらしい。
    • バスが異なるドライブを混在できる。
    • ドライブだけでなくパーティションをも、RAIDに参加させられる。
    • そのため、追加、復旧の際、同じサイズのドライブを探す必要は無い。
  • バスが違っても、ディスクの中身はいっしょ。
  • ここでは書かなかったこと。
    • RAIDを動かしたまま、サイズを大きくすることもできる。小さくすることもできる。
    • ext3のファイルシステムを、マウントしたまま大きくすることもできる。
    • ext3のファイルシステムを、マウントしていなければ、小さくすることもできる。

発展

さらにドライブを1台購入して、USB経由で接続し、RAID1のスペアとして参加させるとすてき。 内蔵ドライブの2台のうち1台が壊れると、生き残った内蔵ドライブとUSB経由のドライブとでの動作に切り替わります。 確かにUSB経由は遅いのだけど、スペアのための同期と、非常時のRAID動作のためだけであるなら、がまんできるでしょう。 ディスクI/Oが極端に高負荷なサーバでは、通常動作時でも足を引っ張ってしまう可能性がありますが。

(2007/1/5 - sgk)