まとめ
- ZFSの中のディスクはログを残さずひっそり壊れてることがあります。注意!!!
- 個別のディスクの状態を確かめたい時は "/usr/local/sbin/smartctl -a /dev/[ディスク名]"を使いましょう。
- (全部を横断的に眺めるときは、裏でディスクに負荷をかけつつ"zpool iostat -v [プール名] 1"しましょう。)
- (FreeBSDでバイナリパッケージを使いたい時はpkg_add -rを使いましょう。)
そんなわけで以下経緯:
(以上2013/4/3 追記)
以前ZFSについてごちゃごちゃ試してたサーバ、まだまだ現役です。
構成:
- HP Proliant MicroServer
- 2TBのディスク5台(raidzでそれぞれのディスク全体を使用)
- 8GBのUSBメモリ(起動用。/bootdirにマウント)
最初のトラブルはNetatalkのドライブが読み書き可能でマウントできなくなったことでした。まだこれは直してないけど、CNID DBが使えないからテンポラリなのを使うよ、リードオンリーマウントだよ、と言われてました。CNID DBを削除しても治らない。
しかし最近はそれだけでなく、sshで入ったときの日々の操作なども、ものすごく遅くなってきました。
- sshで入るときに1分くらい待たされる
- lsと打っただけでまた30秒くらい…
- vimとか起動しようものなら2分くらいプロンプトが返ってこない。
- コマンドライン補完しようとtabを打つたびに30秒は待たされるので非常なストレスが…
なんだこれは!
ディスクやファイルシステムに見えるんだけど、zpool statusしてもエラーはいっこも出てません。dmesgにも異常がないし、コンソールの画面を見ても何も出てません。これって何だろう。起動用のUSBメモリ?CPUのライトキャッシュとか?マザボ死にかけ?
いろいろおかしいんだけど、パフォーマンスが全体的に落ちてるわけではありません。ルータとしての機能にはまったく問題なかったりする。操作の異様な重さからすれば、このマシンを通した通信はもっと物凄く遅いはず。
twitterでつぶやきながら考えることにしました。
USBメモリの状態がおかしくなってないか、あとZFSも個別のドライブ状態とか、もうちょっと詳しく調べたい。
これまで「何が課題であるか」すらよくわかってない感じでしたが、言語化してみることでキーワードを考えついたというか、探す気になりました。ググってみると、hdparmに当たると思われるのはdiskinfoというコマンドらしい。そんなわけでUSBメモリをdiskinfoしてみたところ、10MB/sくらい出ています。むむ。これは現代のHDDに比べると遅いですが、今のひどい状態を説明することはできないよなあ…。
困っていたら、[twitter:@dankogai]がいろいろアドバイスを下さいました。
仰せのとおりに!このzpool iostat -v [pool名] 1というコマンドは、毎秒の転送レートを表示してくれます。
heliopora# zpool iostat -v tank 1 capacity operations bandwidth pool used avail read write read write ---------- ----- ----- ----- ----- ----- ----- tank 3.43T 5.63T 5 14 16.1K 44.0K raidz1 3.43T 5.63T 5 14 16.1K 44.0K ada0 - - 0 11 43.8K 12.0K ada1 - - 0 11 43.9K 12.0K ada2 - - 0 11 43.0K 12.0K ada3 - - 0 10 43.0K 12.0K ada4 - - 0 11 44.0K 12.0K ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool used avail read write read write ---------- ----- ----- ----- ----- ----- ----- tank 3.43T 5.63T 57 0 7.23M 0 raidz1 3.43T 5.63T 57 0 7.23M 0 ada0 - - 0 0 0 0 ada1 - - 0 0 0 0 ada2 - - 0 0 0 0 ada3 - - 14 0 1.81M 0 ada4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool used avail read write read write ---------- ----- ----- ----- ----- ----- ----- tank 3.43T 5.63T 0 0 0 0 raidz1 3.43T 5.63T 0 0 0 0 ada0 - - 0 0 0 0 ada1 - - 0 0 0 0 ada2 - - 0 0 0 0 ada3 - - 0 0 0 0 ada4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- -----
って感じ。裏で dd if=FreeBSD8.2R_DVD.img of=/dev/null とかやりながら実行すると、数K〜数Mバイトが転送されてる様子が見える。でも遅いだけですごく異常な感じはしない。gistに貼って[twitter:@dankogai]にご報告。
ところが、ひと目で返事が返ってきました。
なぬ!?と自分でもgistを見返してみると、たしかに1台だけ挙動が違う! 貼って眺めるのが大事だった…!!
そんなわけで、smartctlを実行…いや、このコマンドは入ってませんでした。portsから入れなければ。
cd /usr/ports/sysutils/smartmontools/
make clean ; make install
なんも考えずにコンパイルに掛かったら、make installにおそろしい時間が。ディスクのおかしいマシンでコンパイルとかありえんよなー。これもFreeBSDまともに使ってない証拠でした。コンパイル済みのパッケージを入れるべきでした。
とのこと。次からそうします!
で、2時間ほど経って、ようやくインストールの済んだsmartctlコマンドを使って/dev/ada3を調べてみると、こんな具合に。(そうか。デバイスを一台ずつ見たい時に使うコマンドはこれだったのか!)
/dev/ada3は完全におかしくなってました。まずsmartctlコマンドになかなかレスポンスが返ってこないのはこのデバイスだけ。そしてsmartctlの出力から、おかしなところだけ抜き出すと:
1 Raw_Read_Error_Rate 0x002f 197 197 051 Pre-fail Always - 830 … 5 Reallocated_Sector_Ct 0x0033 188 188 140 Pre-fail Always - 234 … 196 Reallocated_Event_Count 0x0032 001 001 000 Old_age Always - 218 … 200 Multi_Zone_Error_Rate 0x0008 090 001 000 Old_age Offline - 29448
という具合に山ほどのエラーが。健全な/dev/ada2の同じ部分と比べると明白です:
1 Raw_Read_Error_Rate 0x002f 200 200 051 Pre-fail Always - 0 … 5 Reallocated_Sector_Ct 0x0033 200 200 140 Pre-fail Always - 0 … 196 Reallocated_Event_Count 0x0032 200 200 000 Old_age Always - 0 … 200 Multi_Zone_Error_Rate 0x0008 200 200 000 Old_age Offline - 16
その他の/dev/ada[0,1,4]も健全で、レスポンスも即時でした。
もうada3の異常で決定な感じなので、一度シャットダウンして、予備のSeagate ST32000542ASと交換することにしました。(ホットスワップせずに一度止めたのは、どのドライブがどのデバイス番号だったか、ちょっとあやふやだったため…。向かって左からada0,1,2,3、光学ドライブベイに入ってるのがada4でした。)
このアレイは4台がWD20EARXで、トラブった1台だけがWD20EARS。Seagateのドライブは、たしかセクターサイズが512BytesだったりSATA2だったりして色々違うディスクだったけど、以前テストしてリプレースに使えることは確認済みのもの。
不安だったディスク交換後の起動にもちゃんと成功したので、zfsが認識してるデバイスのリプレースを行います。
# zpool replace -f tank ada3
このSeagateのドライブは、以前このtankというpoolに繋いでテストしたことがあり、メタ情報が残っているため、-f(force)を付けなければなりませんでした。デフォルトで実行されない操作って少しストレスありますね。
でもコマンドはちゃんと通り、自動的にresilverが開始されました。
heliopora# zpool status pool: tank state: DEGRADED status: One or more devices is currently being resilvered. The pool will continue to function, possibly in a degraded state. action: Wait for the resilver to complete. scrub: resilver in progress for 0h7m, 2.14% done, 5h23m to go config: NAME STATE READ WRITE CKSUM tank DEGRADED 0 0 0 raidz1 DEGRADED 0 0 0 ada0 ONLINE 0 0 0 ada1 ONLINE 0 0 0 ada2 ONLINE 0 0 0 replacing DEGRADED 0 0 0 ada3/old UNAVAIL 0 0 0 cannot open ada3 ONLINE 0 0 0 15.0G resilvered ada4 ONLINE 0 0 0 errors: No known data errors heliopora#
ようやく解決!(たぶん!)
[twitter:@dankogai]さんありがとうございました!
それにしても、zpool statusだけじゃエラーが検出できないとは思ってなかったです。ディスクの健全性を検査するスクリプトを書きなおさないと。