2021年3月13日土曜日

S.M.A.R.T.値などで異常を示したST3000DM008で遊んでみよう

新規購入したHDDの初期不良のチェックやRAIDアレイの再構成が一段落ついたので、 先日故障が発覚したHDD(Seagate Barracuda 3.5, ST3000DM008-2DM166)で遊んでみたいと思います。

とにかくドライブのサイズがそれなりに大きいので、一つのコマンドの結果が返ってくるまでに5時間など当たり前なので、一日一コマンドづつしか入力できないのがもどかしいのですが、まあ折角ですので、これまで何度もやっているとはいえ、訓練を重ねることは悪いことではありません。
今回はまず、不良セクタを何とかしたいと思います。


今回の状況としては、/dev/sddとして接続し、ext4の単体ドライブとしてmkfs.ext4をしなおしたうえでrsyncコマンドで元のRAIDの内容をコピーしてある状況を作りました。

まずは異常セクタの特定から行いたいのですが、前回書いた通り、smartctl -t longテストでは異常なしとか平気で言い放つ始末で手に負えません。

実際には以下のパラメータが48まで上昇しているにもかかわらず、です。

・197 Current_Pending_Sector
・198 Offline_Uncorrectable

もはやHDDの自己テスト機能がダメになっているのかもしれません。

そこで、badblocksコマンドを用いて異常セクタを検出したいと思います。

まあ、念のため、再度ブロックサイズを確認します。

1
2
# tune2fs -l /dev/sdd1|grep -i "block size"
Block size:               4096

このパラメータをbadblocksに与えて検査させます。
1
2
3
4
# nohup badblocks -b 4096 -vs -o badblocks.txt /dev/sdd1&
tail -f nohup.out
Checking blocks 0 to 732566271
100.00% done, 5:23:20 elapsed. (139/0/0 errors)
ということで、五時間半かかって、139セクタもの不良セクタが検出されてしまいました。

この段階でのsmart値は以下の通りです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   097   093   006    Pre-fail  Always       -       40328485
  3 Spin_Up_Time            0x0003   096   096   000    Pre-fail  Always       -       0
  4 Start_Stop_Count        0x0032   100   100   020    Old_age   Always       -       6
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       8
  7 Seek_Error_Rate         0x000f   076   060   030    Pre-fail  Always       -       49566908
  9 Power_On_Hours          0x0032   063   063   000    Old_age   Always       -       32571
 10 Spin_Retry_Count        0x0013   100   100   097    Pre-fail  Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   020    Old_age   Always       -       6
183 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
184 End-to-End_Error        0x0032   100   100   099    Old_age   Always       -       0
187 Reported_Uncorrect      0x0032   001   001   000    Old_age   Always       -       262
188 Command_Timeout         0x0032   100   100   000    Old_age   Always       -       0 0 0
189 High_Fly_Writes         0x003a   099   099   000    Old_age   Always       -       1
190 Airflow_Temperature_Cel 0x0022   076   060   045    Old_age   Always       -       24 (Min/Max 20/26)
191 G-Sense_Error_Rate      0x0032   100   100   000    Old_age   Always       -       0
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       4
193 Load_Cycle_Count        0x0032   073   073   000    Old_age   Always       -       55928
194 Temperature_Celsius     0x0022   024   040   000    Old_age   Always       -       24 (0 13 0 0 0)
197 Current_Pending_Sector  0x0012   094   094   000    Old_age   Always       -       1112
198 Offline_Uncorrectable   0x0010   094   094   000    Old_age   Offline      -       1112
199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
240 Head_Flying_Hours       0x0000   100   253   000    Old_age   Offline      -       32556h+15m+05.395s
241 Total_LBAs_Written      0x0000   100   253   000    Old_age   Offline      -       25786278431
242 Total_LBAs_Read         0x0000   100   253   000    Old_age   Offline      -       1151768457351

いやあ、すげえ。Current_Pending_Sector  とOffline_Uncorrectable   が1112にまで上昇してしまいました。
これから試す方法の挙動が楽しみです。

さて、まずは実際にbadblocksコマンドで得たセクタ番号がHDD自身から聞けるかどうか、smartctl -t shortで尋ねてみました。

1
2
# 1  Short offline       Completed: read failure       90%     32571         -
# 2  Extended offline    Completed without error       00%     32452         -


全然教えてくれる気はないようです。

しかし、前回、異常が発生しているにもかかわらずエラーなし(#2です)で正常終了していたのが、read failureで異常終了(#1です)しているのはせめてもの事でした。

異常なしっていう時点でおかしいですもの。


まあ、HDDが異常セクタを教えてくれないとのことですので、それならばbadblocksで検出した139の異常セクタをどうにかすればsmart値はどうなるのかを見ていきたいと思います。


その前に、異常セクタにあるファイルを削除するため、先ほどのbadblocksコマンドで生成された badblocks.txt に記録されているセクタ番号をもとに、debugfsコマンドでセクタ番号から使用されているinode番号を取得して、そのinode番号をもとにファイル名を特定します。


無論、すぐに廃棄する予定のHDDでここまでする必要はないのですが、せっかくの演習ですから壊れても惜しくない大容量HDD(いや、もう壊れているのですが)、有効活用してみたいと思います。


まずは指定したセクタに何らかのデータが記録されているかを調べるには以下です。

セクタ番号が524726232として、icheck <セクタ番号>で調査します。

1
2
3
4
# debugfs -R "icheck 524726232" /dev/sdd1
debugfs 1.42.9 (28-Dec-2013)
Block   Inode number
524726232       117966080

ばっちり使われています。

使われていない場合は次のような表示になります。
1
2
3
4
# debugfs -R "icheck 620236906" /dev/sdd1
debugfs 1.42.9 (28-Dec-2013)
Block Inode number
620236906 <block not found>

これを139セクタ分繰り返します。

ファイル名を得るには
1
#  debugfs -R "ncheck 117966080" /dev/sdd1
というように、"ncheck inode番号" を実行しますと、ファイル名が表示されます。
inode番号は重複する場合がありますので、sortしてuniqしたほうがいいと思います。
数が数ですので、awkなりperlなりpythonなり、スクリプトを書いたほうが安全かと思います。

さて、今回のケースではファイル数に換算すると46ファイルでした。
でかいファイルが配置されていたセクタが多かったようです。

早速それらをunlinkして、smart値を見てみますと、特に意味がある変化は見られません。
当たり前といえば当たり前ですが。

お次はddコマンドで0を書き込んでセクタを代替させる作業を行います。
139セクタすべてを0で埋めますが、その前に1セクタだけやって、smart値がどう変化するかを見てみたいと思います。

1
2
3
4
5
6
7
8
9
10
11
12
13
# dd if=/dev/zero of=/dev/sdd1 bs=4096 count=1 seek=524726232
1+0 レコード入力
1+0 レコード出力
4096 バイト (4.1 kB) コピーされました、 0.00141101 秒、 2.9 MB/秒
# sync
# smartctl -a /dev/sdd1
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
 (略)
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       8
 (略)
197 Current_Pending_Sector  0x0012   094   094   000    Old_age   Always       -       1104
198 Offline_Uncorrectable   0x0010   094   094   000    Old_age   Offline      -       1104
 (略)

おやおや、Reallocated_Sector_Ct   の値は変化がありませんが、Current_Pending_Sector  とOffline_Uncorrectable   の値が2ポイント増えてしまいました。なかなか興味深い事象なので後で遊ぶとして、あと138セクタあるので、残りは一括してスクリプトを組んでゼロで埋めてしまいます。

その結果、
1
2
3
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       8
197 Current_Pending_Sector  0x0012   100   094   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0010   100   094   000    Old_age   Offline      -       0
Current_Pending_Sector  とOffline_Uncorrectable   の値がゼロになり、代替されたセクタが増えていません。
これ、書き込みが成功した場合は代替しないっていうHDDがあることは知っていましたが、このHDDもその一味なのでしょうか。

念のため、これらのセクタを下手に使ってしまわないようにファイルシステムに"コイツはダメだ"と記録しておきます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# fsck.ext4 -l badblocks.txt /dev/sdd1
e2fsck 1.42.9 (28-Dec-2013)
/dev/sdd1: Updating bad block inode.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong for group #18928 (23698, counted=23699).
Fix<y>? yes
Free blocks count wrong for group #19312 (24543, counted=24544).
Fix<y>? yes
Free blocks count wrong for group #20416 (24543, counted=24544).
Fix<y>? yes
Free blocks count wrong for group #22000 (24543, counted=24544).
Fix<y>? yes
Free blocks count wrong for group #22032 (24542, counted=24544).
Fix<y>? yes
Free blocks count wrong (63487139, counted=63487145).
Fix<y>? yes
/dev/sdd1: ***** FILE SYSTEM WAS MODIFIED *****
/dev/sdd1: 97313/183148544 files (1.5% non-contiguous), 669079127/732566272 blocks

ま、結果は信用できませんが、仕上げに自己テストを行わせます。
1
# smartctl -t long /dev/sdd
結果は後日のお楽しみです。(どうせwithout errorでしょうねぇ)

それにしても、3TBという容量が容量なので、こんな危なっかしいHDDをだましだまし使うということは難しい感じです。
廃棄以外にちょっと考えられません。

6TBとか8TBとかがボリュームゾーンになってきている様子ですが、今後ますますトラブル発生即交換・廃棄という運用じゃないととてもやっていけませんねえ。
貧乏性にはつらい選択です。

結果として、頓死しないでずるずる生き延びる、なんだかおもしろい機材が手に入ってしまったので、今後も時間があれば何らかのネタを仕込んでみたい気もしますが、まずは来月あたりにもう一度badblocksコマンドで総なめしてみて、何か面白いことが起きるかどうかですかねえ。

まずは今回はこんなところでしょうか。

ここまでお読みいただき、ありがとうございました。

2021年3月11日木曜日

3年6か月目にST3000DM008に異常発生、WD40EZRZ-RT2購入

一昨日、自宅サーバにて二台のST3000DM008でRAID1を構成していた一台に異常が発生していることが発覚しました。
ペアを組んでいるもう一台のST3000DM008は何の問題もなく元気に稼働しています。

異常は毎週のraid-checkで検出されていました。
よくよく調べてみると、先月のsyslogにすでに異常が報告されていることが分かりました。
smartctlからもmdadmからもメールが来なかったのですっかり油断していました。

2017年6月に運用を開始して以来、メーカーが保証していない24時間365日な自宅サーバ上での使用でこれだけの期間、頑張ってくれたことに感謝です。

実際のところ、ST3000DM001の型番だけ変更品なんじゃないかという疑念が付きまとっていた本製品だけに、一層感謝の念が深まります。


障害の内容は、syslogによるとアクセス不能なセクタが発見されていました。
1
2
3
4
5
6
7
8
9
10
11
12
13
Mar  7 05:57:53 ***** kernel: ata3.00: exception Emask 0x0 SAct 0x100000 SErr 0x0 action 0x0
Mar  7 05:57:53 ***** kernel: ata3.00: irq_stat 0x40000008
Mar  7 05:57:53 ***** kernel: ata3.00: failed command: READ FPDMA QUEUED
Mar  7 05:57:53 ***** kernel: ata3.00: cmd 60/00:a0:00:17:46/01:00:45:01:00/40 tag 20 ncq 131072 in#012         res 41/40:00:38:17:46/00:01:45:01:00/00 Emask 0x409 (media error) &lt;f&gt;
Mar  7 05:57:53 ***** kernel: ata3.00: status: { DRDY ERR }
Mar  7 05:57:53 ***** kernel: ata3.00: error: { UNC }
Mar  7 05:57:53 ***** kernel: ata3.00: configured for UDMA/133
Mar  7 05:57:53 ***** kernel: sd 2:0:0:0: [sdc] tag#20 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE cmd_age=3s
Mar  7 05:57:53 ***** kernel: sd 2:0:0:0: [sdc] tag#20 Sense Key : Medium Error [current] [descriptor]
Mar  7 05:57:53 ***** kernel: sd 2:0:0:0: [sdc] tag#20 Add. Sense: Unrecovered read error - auto reallocate failed
Mar  7 05:57:53 ***** kernel: sd 2:0:0:0: [sdc] tag#20 CDB: Read(16) 88 00 00 00 00 01 45 46 17 00 00 00 01 00 00 00
Mar  7 05:57:53 ***** kernel: blk_update_request: I/O error, dev sdc, sector 5457188664
Mar  7 05:57:53 ***** kernel: ata3: EH complete
驚いてsmartctlで確認したところ、SMART Error Log Version: 1には既に109件もエラーが記録されており、かつ、Reallocated_Sector_Ctの値が8になっていました。

SMART Error Logはこんな感じでした。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
SMART Error Log Version: 1
ATA Error Count: 109 (device log contains only the most recent five errors)
        CR = Command Register [HEX]
        FR = Features Register [HEX]
        SC = Sector Count Register [HEX]
        SN = Sector Number Register [HEX]
        CL = Cylinder Low Register [HEX]
        CH = Cylinder High Register [HEX]
        DH = Device/Head Register [HEX]
        DC = Device Command Register [HEX]
        ER = Error register [HEX]
        ST = Status register [HEX]
Powered_Up_Time is measured from power on, and printed as
DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,
SS=sec, and sss=millisec. It "wraps" after 49.710 days.
 
Error 109 occurred at disk power-on lifetime: 32432 hours (1351 days + 8 hours)
  When the command that caused the error occurred, the device was active or idle.
 
  After command completion occurred, registers were:
  ER ST SC SN CL CH DH
  -- -- -- -- -- -- --
  40 51 00 ff ff ff 0f  Error: UNC at LBA = 0x0fffffff = 268435455
 
  Commands leading to the command that caused the error were:
  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
  -- -- -- -- -- -- -- --  ----------------  --------------------
  60 00 00 ff ff ff 4f 00  19d+18:25:46.787  READ FPDMA QUEUED
  60 00 00 ff ff ff 4f 00  19d+18:25:46.754  READ FPDMA QUEUED
  60 00 00 ff ff ff 4f 00  19d+18:25:46.143  READ FPDMA QUEUED
  60 00 00 ff ff ff 4f 00  19d+18:25:46.015  READ FPDMA QUEUED
  60 00 00 ff ff ff 4f 00  19d+18:25:46.014  READ FPDMA QUEUED

しかしながら、
1
SMART overall-health self-assessment test result: PASSED
なのでsmartctlはメールを飛ばさなかったようです。
ついでにセルフテストを行ってみましたが、こちらも
1
1  Extended offline    Completed without error       00%     32452         -
といわれてしまい、成功終了してしまいました。

兎にも角にも、RAIDが縮退運転に入る前に気づけたことは幸いでした。
早速、気づいたその日にすぐに代替用HDDの選定に入りましたが、最近の手ごろな価格のHDDってほとんどが瓦磁気記録方式(以下SMR)なのでびっくりしました。
確かに、SMRの普及が進んでいるとは噂程度には聞き及んでいたのですが、ちょっと考えてしまいました。

SMRと一言で言っても、大抵はHDDの外周部分をCMRとして使って、あとでゆっくりSMR方式の内周部分に移動する方式が主流のようです。
そのため、毎週テラバイト単位(ベアドライブ単位で丸ごとだから)でのバックアップの処理のパフォーマンスが極端に低下する(CMRとして記録できる領域を超えてしまうため)懸念を抱きました。
また、CMRとして利用するシリンダを酷使することによる耐久性はどうなのかというのも、もう少々、できれば数年、様子を見たいところです。
また、gitでのソース管理などでも、細かいファイルが大量に発生してしまうのですが、これの処理のパフォーマンスも気になります。

まあ、所詮は自宅サーバですし、あまり気にしても仕方がないのですが、面倒になったのでとにかくCMRの製品にしようと思って探してみました。

もともと3TBのHDDだったので3TB近辺で探すと、現在は4TBがお安いようですね。
そのため、1TBはRAIDとしては使えませんが4TBのHDDを探してみると、あっさりWD40EZRZ-RT2という製品が見つかりました。これはCMRなんだそうです。
お値段は8千円。SMR方式の同容量のHDDと比べても最大でも千円前後しか価格差はないようです。

今回異常を示したHDDの先々代がWDでしたが、二年も持たず故障したので、若干気がかりですが、これは我ながら難癖でしょう。
結局のところこういうのはどのメーカでも同じことですし、そもそもメーカが保証しない連続運用が前提な使い方をする以上、すべては自己責任です。
さっそく注文して取り寄せました。

とりあえず例によってmdadmでraid1アレイから故障したHDDをfailさせてremoveします。
(たとえばこんな感じです。sdcが今回壊れたHDDです)。
1
2
mdadm --manage /dev/md0 --fail /dev/sdc1
mdadm --manage /dev/md0 --remove /dev/sdc1
その後、障害が発生したHDDをサーバから物理的に抜去するか、そのまま接続するなら別RAIDに仮参加させるなど元のRAIDアレイに戻らないように工夫した後、 新規購入したHDDのパーティションを元のRAIDアレイのサイズと同じサイズで切って追加します。


パーティションを切る際、partedで開始位置と終了位置をセクタ単位で指定したい場合はセクタ番号の後ろにsをつければ問題ありません。partedでprintコマンドでセクタ単位で表示させたい場合は、
(parted) unit s
とすると表示できます。
もっとも、fdisk -l で事前に見ておいたほうが楽だと思います。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# parted /dev/sdc
(parted) mklabel gpt
(parted) mkpart
パーティションの名前?  []? SDC1-WD4T
ファイルシステムの種類?  [ext2]? xfs
開始? 2048s
終了? 5860532223s
(parted) set 1 raid on
(parted) p
モデル: ATA WDC WD40EZRZ-22G (scsi)
ディスク /dev/sdc: 4001GB
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: gpt
ディスクフラグ:
 
番号  開始    終了    サイズ  ファイルシステム  名前       フラグ
 1    1049kB  3001GB  3001GB                    SDC1-WD4T  raid

その後、partedで余った1TBのパーティションも追加します。
これは正確な数値である必要はないので、開始位置をサイズ、終了位置を100%といったようなアバウトな指定で十分です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(parted) mkpart
パーティションの名前?  []? SDC2-WD4T
ファイルシステムの種類?  [ext2]? xfs
開始? 3001GB
終了? 100%
(parted) p
モデル: ATA WDC WD40EZRZ-22G (scsi)
ディスク /dev/sdc: 4001GB
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: gpt
ディスクフラグ:
 
番号  開始    終了    サイズ  ファイルシステム  名前       フラグ
 1    1049kB  3001GB  3001GB                    SDC1-WD4T  raid
 2    3001GB  4001GB  1000GB                    SDC2-WD4T

余談ですが、もちろん、こんなアバウトな指定のしかたでも、きっちりパーティション2はパーティション1の次のセクタから確保されています(unit sしてprintすればわかります)。
こういった地味だけどとても便利で親切なコマンドを作る気配りというのは、下手をすると余計なお世話になってしまうために目には見えないけれど実際には相当負担が大きいのですが、それをあえてするプログラマの心意気に頭が下がります。

そして、上記で生成したパーティションをアレイに追加すればリカバリが始まります。
1
# mdadm --add /dev/md0 /dev/sdc1

今回のリカバリは夜の20時30分に開始して翌未明02時16分に完了しました。
六時間弱、かあ。するとリカバリ速度は約141,963KB/秒ですね。

ただ・・・容量違いのHDDでRAID1を組むと、新しくて、しかも大きい容量のHDDのほうが先に壊れた経験があるので、今回は先例通りにならないことを願うばかりです。

余談ですが、容量が大きいHDDが先に死んでしまったときに生き残ったHDD(ST31000528AS)は2009/04/24から現在まで元気に活躍していました。
彼の初代の相棒はWD10EADS-00L5B1(2009/04/24運用開始、2011/03/吉日死亡)、次の相棒がST2000DL003(2011/3/22運用開始、2017/06/21死亡)でした。
その後、二代目の相棒の死亡を機にRAIDアレイを引退。
余生をPCクライアントのバックアップ置き場として活躍するものの、2021年3月10日、容量の小ささと古さから廃棄処分となりました。
こちらも、本当によく働いてくれました。
ご苦労様でした。ありがとうございました。

あとは自己診断の結果待ちですが、45,180秒かかるそうなので、初期不良の判定はもうちょっと先になりそうです。
さらに故障が判明してから停止していたrsyncによるraidアレイのバックアップ先との同期やらがあるので当分先の話になりますが、hdparmやddコマンドを用いての単体のHDDの転送速度の実測とか負荷がかかる試験をいろいろ試したいのですが、徐々に進めたいと思います。

ネタのつもりで買ったST3000DM008がここまでしてくれたので、ちょっとうれしくて思わずこのような駄文をひねくってしまいました。
お読みいただきありがとうございました。

---
2021/03/11 追記
異常が発生したST3000DM008をmkfsしなおして、rsyncコマンドでraid1の中身を全コピーしてみたところ、何の異常もなく終了してしまいました。結果は以下の通りです。
1
2
sent 2.80T bytes  received 1.69M bytes  139.56M bytes/sec
total size is 2.81T  speedup is 1.00

RAID1のリカバリ時間とほぼ同等ですかね。おおよそ五時間半かかりました。
それにしても、何の異常もなく正常終了してしまうのには困りました・・・
dmesgにもmessagesにもsmartdctl -aの結果にも、まるで何も記録されていません。
RAIDのアレイ構成員としては恐ろしいのでスペアに指定することなんか想像もできませんが、それはさておいて、3TBもの領域でどう遊んでいいやら。
貧乏性の悩みは尽きませんが、かといって、なんらかのネタを思いつければいいのですが・・・