9/03/2014

[note] データ用HDDの障害復旧、その顛末

ありふれた話ですが、割と大変だったのでメモ。数日前、私用サーバーで久々にトラブルが発生しました。複数繋いでいるデータ用HDDのうち一台で書き込みの異常な遅延が発生したのです。

即座に当該HDDを外し、チェック。下左図はCrystalDiskInfoの画面ですが、回復不可能セクタ等のセクタ異常が多数。寿命と判断し、移行することにしました。なお、HDDの型番はST2000DM001、Seagate製の2TBのもので、運用期間はおよそ1.8年です。保証期間内での故障という事で、予定通りに行かず残念。もっとも、ほぼ24時間の連続運用、S.M.A.R.T.に記録された使用時間は16346時間ですから、一般向けモデルとしてはそれなりに頑張ってくれたと言えなくもないでしょうけれども。しかし読み書きの総量はさほどでもなかった筈だから、やはり期待は下回ったと言わざるを得ず残念です。


ともあれ。面倒ですが、移行・復旧をしなくてはなりません。予備のHDDは同型のもの(ステータスは上図右)を用意してありましたから、これに正常な部分のデータをコピーすればいいわけです。まずはコピー機(これDo台Master)でトライ。今となっては古い型のコピー機なので、35MB/s位のスピードしか出ませんが、問題のHDDは異常に発熱しており、遅い方が発熱を抑える事が出来て良いかもしれない、と思ったわけです。基盤部の発熱であればあまり意味は無いのかもしれませんけれども、気休め的に。しかし触って火傷するレベルの発熱というのは。。。

2台を繋ぎ、コピー設定にして実行し放置。数時間後、数百G進んだあたりでエラーセクタにあたったらしく、ビープ音が鳴り響きます。このコピー機には、手動ながらエラーセクタのスキップ機能が付いています。ダイヤルとボタンを操作し、リトライとスキップを適当に繰り返すと、十数程度セクタを飛ばした所でコピー再開。やれやれ、とため息を付きつつ、また放置。

そして数時間後、再びのビープ音。1300G弱、およそ2/3弱の辺りでエラーセクタ。また手動で一つずつセクタをスキップします。が、今度はなかなか、というか全然終わらない。数十回やっても終わりません。ここは大きすぎて手動では無理か、とそこで一旦諦め、現在のセクタ位置をメモした上でストップしました。

しかし、2/3程度まで殆どコピー出来た事から、ドライブの基盤やヘッダ周りの機構、各機能自体は正常で、単に途中でエラーセクタが多めに発生しているだけだろうと判断出来るわけで、かつて遭遇し、トラウマともなったWD20EARSのそれとは異なるものと理解して少し安心。なので、ここからは単にエラーセクタを回避して残りの正常部を回収する、ソフト的な対応に切り替える事に。

残り部分のコピーには、linuxのサルベージツールの定番、GNU ddrescueを使用しました。ddrescueを選択した理由は、エラーブロックをスキップしつつ、ファイル(デバイスファイル含む)をバイナリコピーするツールです。途中での中断・再開が可能な事と、任意の領域だけを対象にコピーする機能がサポートされている(当たり前と言えば当たり前ですが)もの、という条件に合致する中で最も標準的に使われるものだったからですね。

サブの各種テスト等作業用デスクトップPCにコピー途中の当該HDD2台を繋ぎ、Ubuntuを立ち上げます。当該HDDのデバイス名は、オリジナルがsda、コピー先がsdc。これについて、既にコピーが完了している1300G弱を除く700G強の領域を対象にコピーをかけたのです。コマンドは下記。

# sudo ddrescue --force -r 3 -i 0x12B04BE0000 -o 0x12B04BE0000 /dev/sda /dev/sdc rescue_sda_sdc.log

なお、各オプションの意味は次の通り。--forceがデバイス全体を対象にする場合の実行オプションで、誤ってデバイスを破壊しないためのものですね。-rはリトライ回数。デフォルトでは0ですが、これは不要だったかもしれません。-iはコピー元側の開始地点、-oはコピー先側の開始地点。コピー機でエラーセクタが発生した箇所の直前の同じ場所を指定しています。後ろ3つはコピー元、コピー先、ログファイル名。

何せコピー先は完全に上書きされてしまいますから、万が一にも間違いのないよう、ファイルへの一部書き出し・比較等の動作テスト等も繰り返し行い、コマンドも入念に確認した上で実行。

すると、当然ながら即エラーセクタにぶち当たり、リトライと諦めてスキップ、を繰り返しながらえっちらおっちら進みます。100K強程スキップした後、コピー再開。大体45MB/s位で快調に。

それからおよそ一時間。もう大丈夫かな、と思いきや、さにあらずで再びエラーセクタ。今度はなかなか終わりません。スキップして再開した、と思ったらまたすぐエラーセクタ、を断続的に繰り返します。それでも延々と待っていると、総計6MB程スキップした後にコピーが再開されました。そこからは最後まで問題無し。被害の範囲が確定され、その程度か、と一安心です。

なお、ddrescueの処理はまだ続きます。1度目のトライでは大雑把な処理、すなわちやや大きめのブロックでリトライ無しで行うらしく、抽出されたエラー箇所でのリトライと細分化しての個別処理をそれぞれのステップに分けて再度行うのですね。それぞれ、"Trimming failed blocks..."と"Splitting failed blocks..."というメッセージが出ます。で、Splittingの方は何時間も変化しない状態が続いたのでその途中でCTRL-Cを入れて打ち切りました。最終的には下記のような状態です。

<ddrescue打ち切り時のステータス>

rescued:   716122 MB,  errsize:   1778 kB,  current rate:        0 B/s
   ipos:     1411 GB,   errors:      93,    average rate:   29147 kB/s
   opos:     1411 GB,    time since last successful read:    27.9 m
Splitting failed blocks...

結局、エラー領域のサイズは1778KB、1段階目の1/3以下にまで縮小しました。エラー回数は93回。対象領域サイズ700GB超と比較すればよくここまで抑えられたと言うべきでしょう。

これで、エラーでコピー出来なかった領域がファイルシステムの上位管理領域にかかっていなければ、いくらかの末端ファイルの破損で済む、というわけです。

で、若干どきどきしながらサーバに再接続します。当然ながら入るディスクチェックを見つめることしばし、無事起動してくれました。いや、データドライブなのだから元々起動には関係ないのですが、その後急いでファイル類を調べて見ても、ディレクトリに欠損は見られず、普段アクセスするファイル類にも特段の欠落は見られません。

というわけで、これでようやく作業完了です。最初の不具合認識からここまで、およそ丸2日。精神的に疲労しましたが、概ね復旧出来てめでたし。

もちろん、最初からRAIDを組んでおけばこんな苦労する必要もなかった筈なのですが、ドライブは複数あるわけで、その全てにRAID1とか5とか6となると、常時十数台のHDDを運用する羽目になるし、個人のサーバとしてはコスト的に厳しいところです。ということで止むなくこういう、障害、その兆候を認識したら直ぐに復旧に移る運用にしているわけなのですが、やはり綱渡りですね。システム系はバックアップも割とマメに取っているのですけれども、その範囲や方法を少し見直した方がいいのかも、と反省しきり。しかしこれだけストレージのサイズが大きくなると、バックアップを取るのも時間がかかりすぎるし、どうするのが適切なのか、悩ましいところです。さしあたり、優先度の設定が必要ですかね。

ともあれ疲れました。 やれやれです。

<その後>

移行後のドライブの動作自体は特に支障も無いものの、結構ファイルが消えている事が判明しまして。エラー領域が途中のリンクに引っかかってたようで、幾つかのフォルダ中に入れてあったファイルのうち、1/10位の消失が確認されました。当該フォルダのファイル数は10000位でしたから結構な数で、消失データは再度作成可能なものだった事は不幸中の幸いではありますが、とても面倒で困りました。どうするべきか、悩ましいところであります。ちなみにファイルシステムの形式はext4で、FAT系やNTFS等に比べればこういう大量消失は起きにくい筈だったんですけど。何にせよこの種の消失は検知し辛いものですから、ここ以外にも消失がある可能性も否定出来ません。困ったものです。

なお、外したドライブは後日RMAしました。
[note] SEAGATE製HDDをRMA

[関連記事 [note] WD製HDD故障再び]
[関連記事 [note] WDのHDD破損が再発]
[関連記事 [note] WDのHDDでファイル破損頻発]