Software RAID
起稿 1999.08.02
更新 2005.12.19

「RAID5が逝きましたを」追記しました。(2005.12.19)


最近、RedHat 7.2 を設定する機会があったので、
RedHat 7.2 で ルートパーティションを RAID1 にして GRUB で起動する」を追記しました。(2002.11.01)


Linux World 2002年3月号
実践!RAIDシステムの原稿を置きました。(2002.06.25)


最新のRAIDパッチはここにあります。(2001.07.05)
http://people.redhat.com/mingo/raid-patches/


Software-RAID HOWTO 日本語訳 sgml版 HTML版 TEXT版 (1999.11.08更新)
この版によると、また一つSoftware-RAIDが進化しました。
RedHat Linux 6.1 のグラフィカ ル・インストールでは、mdデバイスへのインストールが可能になり、
また、RAID-1 のみですが、 mdデバイスからブートできるlilo 21 へのパッチ も利用可能になっているようです。


Linux USER 発売(1999.12.17)
編集 ・・・ UNIX USER 編集部
発行所 ・・・ ソフトバンク パブリッシング(株)
私の記事が載っています。

2000.6.12 もう、近所の本屋で見かけることもなくなったので、記事の原稿をアップしておきます。

IDEハードディスク+最新ソフトウェアで作る
RAIDシステム構築レシピ
というものです。
しかし、致命的な誤植を発見しました。

p.127 左上

failed-disk   1
の行を
raid-disk     13

ありゃりゃ、raid-disk 1
でなければ動きません。

こういう「絶対間違えてほしくない」ところは、直接画面からコピー&ペーストで
持ってきてるのに、なぜこんなことが起こるのでしょうか?不思議です。
UNIX USER 編集部でも調査中とのことですが、最終の校正時にはなかったミスです。

ま、とりあえず、また何かミスが発見されたら、ここに書くようにしますので。よろしくお願いします。



どうもLinuxのSoftware RAIDの世界は、とっても変化が激しいらしい。
LDPのSoftware-RAID HOWTOや
JFのRoot-RAID-HOWTOは、すでに内容が古くなっています。(1999.8.2時点) 

と、以前に書いたのはちょっと不正確でした。(9/10)
現在のところ、Kernelは2.2.12まで出てますが、これには標準でSOFTWARE RAIDが組み込まれています。(2.2.0から)
しかし、実は、
ftp://ftp.gz.us.kernel.org/pub/linux/daemons/raid/
とか
ftp://ftp.gz.jp.kernel.org/pub/linux/daemons/raid/といったサイトには(これらはみんなkernel.orgのミラーサイトです)
alphaというディレクトリ(要するにftp://ftp.gz.us.kernel.org/pub/linux/daemons/raid/alpha/などですね)
というのがあって、そこに
raid0145-19990824-2.2.11.gz
といったアーカイブがあり、いわゆる最新版RAIDパッチなんですが、
これは現状の2.2.12などのkernelに実装されているRAIDとは互換性がないんです。

(2.2.12をリリースする前に、このパッチを正式に取り込むかどうかで、議論があったようです。結局、取り込まれませんでした。)

raidtoolなんか、コマンド名も変わってるし。

でもね、私はこれしか使ったことがないし、古いものに比べたら圧倒的に使いやすいのです。(あ、「と思います」です)
最大の特徴は、「RAIDの自動検出」機能があるということでしょう。

今日、調べたところによると、
linux-2.2.11については、
raid0145-19990824-2.2.11.gz
raidtools-19990824-0.90.tar.gz
が最新です。

Software-RAID HOWTOについては、上記パッチに付属の文書を読むべきです。
LDPにある文書と比較すると、内容が、がらっと変わってしまっています。
Root-RAID-HOWTOの内容まで含まれています。

現在のところ、Root-RAID-HOWTOについては、JFに日本語訳があります。
実は、私はRAIDをルートパーティションにして使いたくて、最初はこれを読んだんです。

しか〜し、

難しすぎて挫折しました。

原文も日本語訳も、それほど古いものではないんですが、
内容的には、最新のSoftware-RAID HOWTOと比較すると、まったく違うものです。
なんたって、そもそも対象としているSoftware-RAIDのバージョンが違うのですから。

このバージョンのSoftware-RAID HOWTOについては日本語訳は見あたりません。
私が翻訳してやろうなんて、大それた考えを起こし、一度は挫折したんですが、
どうにかできあがりました。
Software-RAID HOWTO 日本語訳 sgml版HTML版 TEXT版
オリジナルのURLはhttp://unthought.net/Software-RAID.HOWTO/です。

訳中にも書きましたが、このHOWTOの書き方は、かなり不親切です。実際に適用するには、
読んだだけで理解できるだけのスキルは必要かと思います。



さて、実例です。

私は面倒くさいので、以下の作業はすべてroot権限で行いました。
書き方がいいかげんなのは筆者の性格を反映しています。
あくまで「あなた自身の責任」でお願いします。

とりあえず・・・
kernelは2.2.10を対象にします。
まず上記サイトから2.2.10用のパッチとraidtoolを拾ってきます。
で、パッチを当て、kernelを再構築します。
私はRAID1を使いました。
このときに、RAIDの自動認識をチェックしておくべきでしょう。
で、再起動。

raidtoolについては、/usr/srcにでも展開すると、
/usr/src/raidtools-0.90
というディレクトリができますから、そこに移動し、
./configure
make
make install
で出来上がるようです。

まずは、ルート以外のパーティションでやってみるのが順序としてはいいでしょう。

RAID用のパーティションを用意して下さい。
(書きながら思ったけど、最初から用意するべきですよね?)
私はRAID1でやりましたので、
/dev/hda3と/dev/hdb3をRAID1にすることにしました。当然、これらのパーティションはマウントされていてはいけません。

RAIDを自動認識させるためには、これらのパーティションに細工をします。
fdiskでパーティションタイプを0xfdに設定します。(Linux nativeは0x83、Linux swapは0x82という、例のアレです)

で、
/etc/raidtab
を作成します。(RAIDの設定ファイルですな)
内容は、

raiddev /dev/md0
raid-level 1
nr-raid-disks 2
nr-spare-disks 0
chunk-size 4
persistent-superblock 1
device /dev/hda3
raid-disk 0
device /dev/hdb3
raid-disk 1

てな具合です。詳細はSoftware-RAID HOWTOを読んで下さい。
自動認識させるには、
persistent-superblock 1
が必要だそうです。(私、最初はこれを忘れました。でも問題なくできちゃった・・・)

さて、RAIDを構築します。
コマンド一発。

mkraid /dev/md0
(このコマンドは、ディスク容量に応じて時間がかかります)

これでRAIDパーティションができました。

この時点で再起動すると、/dev/md0が自動認識されるはずです。

でも、Linuxで使えるようにするためには、更に、

mke2fs /dev/md0

が必要です。
わかる人にはわかる。RAIDパーティション上にext2ファイルシステムを構築するわけです。

ここまで来たらmountして使えます。
このままで良ければ、/etc/fstabに書いておけば、自動的に使えちゃいます。

RAIDの状態は
cat /proc/mdstat
とやると表示されます。(kernel構築時にproc file systemを忘れないでね) 



 

何かあったら?
さて、せっかく構築したRAIDです。何かあったらどうなるんだろう?

たとえば、shutdownをきちんとやらずにいきなりresetボタンを押す。(良い子はマネしないように)

なんと!
raid1syncdとかいうデーモンが勝手に動いて修復してくれるではないか!

偉いのはこれだけではない。RAIDの修復はそこそこ時間がかかる。10GBのHDでは2時間は最低覚悟が必要。
(cat /proc/mdstat を実行してみると、概略の残り時間がわかります)
しかし、修復作業を開始した直後、動作可能となってしまう。
RAIDの修復をしながら、平然と使えてしまうのである。

いきなりresetのあとは「前回、きちんとumontしなかっただろ?」とか怒られながら、
強制的にfsckが動くが、これもすんなり普通に終わってしまう。
???かなりショックである。良くできている。

もう一つ。片方のHDをはずして起動してみる。
RAIDとしては片肺運転なのだが、とりあえず問題なく動く。

もう一度HDを付けなおしてみると、さすがにそのままでは片肺のままである。
しかし、たとえば、はずしたのが/dev/hdb3だったら、
raidhotadd /dev/md0 /dev/hdb3
とやると、再構築を始めてくれる。「なんて偉いんだ!!!」と思ってしまう。
(RAIDだっていうんなら当たり前なんだろうけどね)

注:本当に片方のHDが壊れた場合、/dev/hdb3を新たに用意して、fdiskでパーティションタイプを0xfdにしてから
raidhotaddコマンドを実行しなければならない。
このとき、その新しいHDが既に他で使われていたものだとすると、警告が表示されることがある(特にLinuxで使っていたものだと)
つまり、本当にそのままraidhotaddを実行してしまうとHDの内容を破壊する危険が伴うので、警告を発するわけだ。
この警告が出ると、そのままではRAIDの再構築ができない。

どうすればいいのかはその警告文の中にしか書かれていない。
そのメッセージを見ることになった時点で、読んで下さいな。 


さて、私の目標はルートファイルシステムとしてRAIDを使うことなのだ。(1999.09.28追記)
 
ここで大問題があります。

bootの時点で、RAIDが認識されなければ、RAIDパーティションからbootすることはできません。今のところ、liloやらloadlinはRAIDを認識してくれませんので、どうにかして最初にkernelを起動しなければならないわけです。

その方法としては、

(1)FDにkernelだけ入れてFDからブートする。
(2)RAIDでないHDパーティションにbootできる環境を構築して、そこからbootする。
(3)その他に、とにかく、bootできるデバイスを用意して、そこからbootする。

kernelさえ起動すれば、RAIDを認識した後で、RAIDをrootディレクトリとして動き始めることはできるわけです。
私の場合はM-Sytemsという会社のDiskOnChip2000というものを使ってみました。
これはこれでLinuxで使えるようにいろいろあるんですけどね。
詳しい話をすると、一章使っちゃうレベルなんで、別の機会にしましょう。(・・・予定は・・・未定?)

この先の話は、Linuxのbootについては理解しているものとして、話を進めます。(なんて強引なんだ)

さて・・・
私が読んだ時点でのSoftware-RAID HOWTO(V0.90.2-Alpha 27th february 1999)には、こんなことが書いてありました。
正確な翻訳ではありません。私が理解した範囲でのことですからね。
ここの話は、IDEディスクの2つのパーティションをRAID1(ミラーリング)として使うという前提としましょう。

1.同じHDを2台用意し、PCに実装する。
 仮に、この2台を/dev/hdaと/dev/hdcとしましょう。

2.もう一台、別のディスクを用意して実装し、そこにLinuxのdistributionをインストールする。
 仮にこのディスクを/dev/hdbとします。
 パーティションは/dev/hdb1だけで通常は十分でしょう。
 要するに・・・
 RAIDに構築してしまうと、デバイスは/dev/md0などという名前になるわけで、
 今のところ、私が知る限り、/dev/md0というパーティションにインストール
 できるdistributionは存在しないわけです。そこでこういう面倒なことをします。

3.それらに同じようにパーティションを切る。
 例えば/,/boot,swapの3つ。私の場合は/とswapだけにしました。
 このうちの/をRAIDにしてroot ディレクトリとして構築するわけです。
 

 そうそう、swapパーティションはRAIDにするなって書いてあったっけ。
 なんでかって?よくわかりませんが、知りたい方は原文を読んで下さい。(^^;;;
 (私のいい加減な理解によると、swapが必要な状況は、実メモリが足りないわけで、
 そこでRAID構成のswapを使おうとすると、そのためには実メモリが必要で・・・っていう
 状態に陥っちゃうとかなんとか)
 そうすると・・・
 RAIDの目的を考えると、十分なメモリを積んで、swapは使わないっていうのが正解かも。
 しか〜し!
 本日(10/5)、最新のHOWTOを確認したところ、最新版のpatchでは、この問題は解消されているようです。
 なんとも変化の激しいことです。


4./dev/hdb1の上で、前述のパッチを当てたkernelを用意し、
 RAID対応にコンパイルし直すわけです。
 /dev/hdb1から再起動すると、RAIDの構築の準備が整いますので、
 例えば/を/dev/hda1と/dev/hdc1とすると、これらのパーティションをRAIDとして構築
 し、自動検出できるようにします。
 例としては/dev/md0としましょう。
 これをext2ファイルシステムとします。
 /dev/hdb1から再起動すると、/dev/md0が自動認識されるはずです。

5./dev/hdb1のシステム全体を/dev/md0にコピーします。
 このときには、生々でコピーするコマンドを使うわけには行きません。
 原文では、確か、「生々コピーコマンドは使わずに、tarを使うように」などと書いてあ
 りました。
 私の方法は、
 まず、/dev/md0はマウントしないでおきます。
 で、/にいる状態でシステム全体をtarで固めます。zオプションを付けて圧縮するのが
 いいでしょう。
 (この方法では/dev/hdb1には、固めたものを置いておく余裕が必要です)
 その後、/dev/md0を/mntなどにマウントして、tarで固めたものをコピーし、解凍します。

 あ、ついでにいうと、私は固めるときに、/procファイルシステムはマウントしない
 ようにしておきました。
 (tarのオプションを工夫したり、パイプを使ったりしてコマンド一発でできるらしい。ま、いいじゃん)

6.2つの/bootパーティションにLinuxをbootできる環境を構築します。(これらはRAIDにしません)
 liloでもloadlinでもいいでしょう。
 kernelはrootを/dev/md0として起動するように設定します。
 liloを使うなら、root=0x900とでもしてください。
 /dev/md0はmajor=9、minor=0ですから、0x900になるんですが・・・
 rdev vmlinuz /dev/md0
 とでもすれば、FDにkernelを入れておくだけで起動します。
 rdev vmlinuz 0x900でも同じでしょう。

7.BIOSの設定をします(こんなのできるのかな?自分ではやってみてないんです)
 /dev/hdaと/dev/hdcのどちらの/bootからでも起動できるようにするわけです。
 どちらもboot可能にしておき、BIOSではAutoに設定しておけば、できるのかも。
 要するに、どちらかが壊れた場合に、生き残ったディスクから起動させるわけです。
 こうしなければ、rootをRAIDにする意味ないでしょ?
 そうそう、緊急用に、RAIDを認識するkernelの入ったFDを用意しておくのもいい手ですよね?
 注意点として、/bootパーティションを/etc/fstabに記述してはいけません。そんなことをすると、
 万一、片方のディスクが壊れたときに、存在しないディスクをマウントしようとして、システムがスタックします。

8.再起動すると、/bootから起動してから、/dev/md0をrootして動作開始します。
 /etc/fstabの記述もきちんとしておきましょう。
 念のため、両方の/bootから起動してみましょう。
 ここまで来れば/dev/hdbには用はありません。


実運用中のお話(2005.09.28追記)

私が管理しているマシンでの運用中の実例です。
管理用コマンドの実使用例としてでも読んで下さい。
raidhotremove、raidhotadd、raidsetfaulty という3つのコマンドの使い方です。

このマシンでのmd1 は、本来、 hdg1[2] hdf1[1] hde1[0]
という状態であり、hdh1 が予備として設定されていました。
昨日、ちょっとしたエラーで hde1 が外され、予備のhdh1が自動的に組み込まれてしまいました。
そういう状態から話は始まります。

まず、

# raidhotremove /dev/md1 /dev/hde1
を実行して、hde1を md1 から切り離し、
# fdisk /dev/hde
で見てみると、別に異常がないようなので、(時々こういうことは起こるようです)
# raidhotadd /dev/md1 /dev/hde1
を実行して、再度 md1 に組み込んであげたところ、
↓現状としてこうなりました。(md0とmd2は無視してね)
# cat /proc/mdstat
Personalities : [raid1] [raid5] [multipath]
read_ahead 1024 sectors
md0 : active raid1 hdb1[1] hda1[0]
      38748672 blocks [2/2] [UU]

md2 : active raid1 hdb2[1] hda2[0]
      329216 blocks [2/2] [UU]

md1 : active raid5 hde1[3] hdh1[0] hdg1[2] hdf1[1]
      241254528 blocks level 5, 4k chunk, algorithm 2 [3/3] [UUU]

unused devices: <none>
なぜか4つのパーティションが正常に動作しているように見えてしまうようで???
で、もともとはhdh1が予備なので、元の状態に組み換えたいと思ったのです。
しかし、この状態から
# raidhotremove /dev/md1 /dev/hdh1
を実行しても、
/dev/md1: can not hot-remove disk: disk busy!
と、怒られてしまいます。どういう状態なんだろう?
よくわからないけど、試しに
# raidsetfaulty /dev/md1 /dev/hdh1
を実行(hdh1 をわざと故障モードにしてみたわけです)すると、
こうなりました。
# cat /proc/mdstat
Personalities : [raid1] [raid5] [multipath]
read_ahead 1024 sectors
md0 : active raid1 hdb1[1] hda1[0]
      38748672 blocks [2/2] [UU]

md2 : active raid1 hdb2[1] hda2[0]
      329216 blocks [2/2] [UU]

md1 : active raid5 hde1[3] hdh1[0](F) hdg1[2] hdf1[1]
      241254528 blocks level 5, 4k chunk, algorithm 2 [3/2] [_UU]
      [>....................]  recovery =  0.0% (38528/120627264) finish=52.0min speed=38528K/sec
unused devices: <none>
どうやら、hde1は予備として組み込まれており、
hdh1が故障したので自動的に修復が始まったという状態のようです。賢い!(?)

これで hdh1 に(F)マークが付いたので、
# raidhotremove /dev/md1 /dev/hdh1
を実行し、hdh1 を外します。
そしてもう一度
# raidhotadd /dev/md1 /dev/hdh1
を実行して hdh1 を組み戻すと……
# cat /proc/mdstat
Personalities : [raid1] [raid5] [multipath]
read_ahead 1024 sectors
md0 : active raid1 hdb1[1] hda1[0]
      38748672 blocks [2/2] [UU]

md2 : active raid1 hdb2[1] hda2[0]
      329216 blocks [2/2] [UU]

md1 : active raid5 hdh1[4] hde1[3] hdg1[2] hdf1[1]
      241254528 blocks level 5, 4k chunk, algorithm 2 [3/2] [_UU]
      [>....................]  recovery =  4.9% (5979292/120627264) finish=68.3min speed=27957K/sec
unused devices: <none>
どうやらきれいに元の状態(厳密にはちょっと違いますが)に戻せたようです。
最後に組み込んだ hdh1 は予備として正常動作しているものと推測されます。

RAID5が逝きました(2005.12.19追記)

私が管理しているマシンでの運用中の実例第2弾です。

上記で↓こういう状態だったRAID5のデバイスについてです。

md1 : active raid5 hde1[3] hdh1[0] hdg1[2] hdf1[1]
      241254528 blocks level 5, 4k chunk, algorithm 2 [3/3] [UUU]
md1は3台(hde,hdf,hdg)のHDDでRAID5を構成し、1台(hdh)は予備です。

まず、hde1が逝ったので、予備のhdh1を動員して再構築が始まりました。
md1 : active raid5 hdh1[4] hde1[0](F) hdg1[2] hdf1[1]
      241254528 blocks level 5, 4k chunk, algorithm 2 [3/2] [_UU]
      [>....................]  recovery =  3.6% (4388936/120627264) finish=95.3min speed=20318K/sec
その再構築の最中にhdg1が逝きました。
md1 : active raid5 hdh1[4] hde1[0](F) hdg1[2](F) hdf1[1]
      241254528 blocks level 5, 4k chunk, algorithm 2 [3/1] [_U_]
死亡確認です。(涙)

予想もしていなかったことって、起こるんですね。
この事件はサーバーからバックアップ機にバックアップを取っている最中に起きました。
バックアップのためにHDDに負荷がかかる状態だったので、2台のHDDが相次いで逝ってしまったのです。
バックアップ機を用意しておいたことで最悪の事態は防ぐことができましたが、まったく被害がなかったわけではありませんでした。
RAIDを組んでいるからといって安心していると痛い目にあいます。

戻る

有限会社かさい電算工房 取締役 笠井 宗