月曜恒例のシステムダウン… なんかホッテントリに入るとダウンしてるような気がする。
今回はファイルサーバのRAIDがおかしくなった模様。RAIDの2つが飛んだので、ダウン。無理やりの再構成をしたら、ウェブサーバのイメージが損傷していたので、それを復元するのに時間がかかった。
ということで、メモ代わりにやったことを書いておく。
原因はsyslogを見てもよくわからないのだが、どうやら何らかの理由でRAIDに不整合が起きたらしく、そこでアクセスに失敗するのでボリューム(DE)異常とみなしてボリュームを外していたらしい。2つ目を外した時点でRAIDは閉塞。運の悪いことに、ちょうどこの異常が発生するところに、ウェブサーバの/homeのイメージがあったようだ。
まず、無理やりにRAIDを構成させる。
# mdadm -A /dev/md0 -u 077f1311:1fa71427:c3d63b96:fccdb942 --run --force
こうすると、縮退モードでRAIDが起動する。ここで、落ちていたDEを消去して再投入をすると、再構成が始まる。
# mdadm --zero-superblock /dev/sdd1 # mdadm /dev/md0 -a /dev/sdd1
この隙に、救えるディレクトリは出来る限り他の空間に退避させて、再構成完了を待つ。これで上手く行けば万々歳なのだが、世の中そんなに甘くない。ほとんど終了しようかというところで不具合を発見されて、再構成がコケる。/homeのイメージはちょうどこのコケるあたりを含んでいて、イメージを他のスペースにコピーしようとすると、終わる直前くらいでコケる。
ちなみに、イメージはreiserfsで作られている。reiserfsはイメージの先頭だけではなく、末尾付近にも重要な情報を保持しているので、途中までコピーされていてもまるっきり使いものにならない。
そこで、問題のイメージをコピーなしでloopback mountしてみる。
# mount -o loop home.img ./home
これ自体はジャーナルを再試行するだけで正常に完了する。つまり、「問題の箇所」は未使用領域だということ。
そこで、まずコピー出来るだけ他の領域にコピーする。そうしているうちに処理はコケるので、そこでコピーは完了とする。
このファイルは実際のイメージよりも小さいので、とりあえず残りの部分にゼロを書き込む。
# dd bs=1M seek=679789 of=home.img if=/dev/zero count=20211
これで元々のイメージと同じサイズにしておいてから、
# dd bs=1M seek=679791 skip=679791 of=home.img if=/md0/home.img
途中、「コケる領域」があるはずなので、その領域を過ぎたあたりからコピーする。これでコケずに最後までコピーが出来た。そこで、念のためにfsckをしてみると、何の問題もなく完了する。つまり、無傷のイメージが再生出来たことになる。
後はまぁ適当にどうとでもしてやればいいだけ。
どうもうちではファイルサーバ絡みの障害が多いので、一応ファイルサーバを使うのはやめることにした。現状、/homeのイメージはローカルに、DB領域はファイルサーバにという構成に変更した。
つーことで、普通は諦めてしまうような障害も、ちょっとした工夫で無傷で復元出来るわけです。