USBメモリでRAID 5を構築・スクラビング
USBメモリのRAIDでもスクラビングは必要だろうか?
RAIDのメンテナンスには定期的にスクラビングするのが良いそうな。スクラビングとは、保存されているデータを読み出して、データの同一性、整合性をチェックすることです。ところで、USBメモリで構成したRAIDでもスクラビングした方が良いのでしょうか?
ソフトウェアRAIDのmdadmにはアレイを構成しているデバイスの故障監視、通知機能があり、ウチの場合もこの機能を有効にしています。しかし、どんな故障の仕方をしたら検知されるのでしょうか?
HDDやUSBメモリなどの記憶装置の壊れ方には幾つかあって、
- 装置がデバイスとして認識されない。
- デバイスとしては認識されているが、記録されていたデータやパーティションが消失している。
- デバイスは認識され、保存されていたファイルは存在しているが読み出せず、書き込みもできない。
- デバイスは認識され、保存されていたファイルは正常に読めるが、書き込みができない。
- デバイスは認識され、保存されていたファイルは正常に読めるが、読み出したデータの一部または全部が壊れている。書き込みは正常にできるが、暫くして読み出してみるとデータの一部または全部が壊れている。
- デバイスは認識され、書き込みは正常にでき読み出してみてもデータは正常だが、ある程度時間が経っている一部のファイルを読み出してみるとデータの一部または全部が壊れている。
- デバイスは認識され、正常に読み書きできるが、レスポンスが非常に悪い(何度かリトライを繰り返している様子)。
- デバイスは認識され、正常に読み書きできるが、S.M.A.R.T.等で診断してみると故障の予兆が現われている。
などなど。当然、1.が最も重症で、下にいくほど軽症ということになります。このうちmdadmの故障監視で検知できるのは、1〜4 or 5くらいまでじゃないかと思います。と言うのも、所詮ソフトウェアRAIDなのでI/Oエラーかデータの不整合を故障の契機にするしかないのではと考えるわけで。
となると、5.の正常に書き込めた直後や、6.の当該ファイルの読み出しを行っていない間は、故障していても検知されないって事になります。まして、7.や8.ともなると検知は難しいと思われます。
そこで、スクラビングという事になります。定期的に保存されているデータを読み出して整合性をチェックしてやれば、5.と6.のパターンでも早期に故障検知できるのではないかというわけです。それにUSBメモリの場合、5.や6.のパターンって結構ありそうな気がしますね。
スクラビングは以下の手順で行います。例えば/dev/md0 の場合は、
"/sys/block/md0/md/sync_action" ファイルの内容がidle であることを確認する。
"/sys/block/md0/md/sync_action" ファイルにcheck を書き込むとスクラビングが始まる。
- スクラビングの進行状況を
"/proc/mdstat" ファイルで確認する。
- スクラビングが完了したら
"/sys/block/md0/md/mismatch_cnt" ファイルに書かれている不良ブロック数が0であるか確認する。
となります。これを定期的に実行してやれば良いわけですが、各ファイルのパス名が長くて憶えてられないし面倒なので、以下のようなスクリプトを作ってみました。
#!/bin/sh
DEV="md0"
MD0="/sys/block/$DEV"
MD0MD="/sys/block/$DEV/md"
RAID_SYNC="$MD0MD/sync_action"
MISMATCH="$MD0MD/mismatch_cnt"
MDSTAT="/proc/mdstat"
usage()
{
echo "$0 [start|stop|status|detail|repair]" >&2
exit 2
}
md0_exists_check()
{
if [ -d $MD0 ]; then
return 0
fi
echo "RAID($DEV) device is not exists." >&2
exit 2
}
sync_exists_check()
{
if [ -e $RAID_SYNC ]; then
return 0
fi
echo "¥'$RAID_SYNC¥' is not exists." >&2
exit 2
}
idle_check()
{
sync_stat=`cat $RAID_SYNC`
if [ $sync_stat != idle ]; then
echo "RAID($DEV) device is busy. Try later." >&2
exit 2
fi
return 0
}
if [ $# -ne 1 ]; then
usage
fi
md0_exists_check
sync_exists_check
case $1 in
start) idle_check
echo check >$RAID_SYNC
;;
stop) sync_stat=`cat $RAID_SYNC`
if [ $sync_stat = idle ]; then
echo "RAID($DEV) device has already stopped." >&2
exit 2
fi
echo idle >$RAID_SYNC
;;
status) cat $MDSTAT
miss_cnt=`cat $MISMATCH`
if [ $miss_cnt -eq 0 ]; then
echo "No bad block."
else
echo "RAID($DEV) device has $miss_cnt bad blocks!"
fi
;;
detail) mdadm --detail /dev/$DEV
;;
repair) idle_check
miss_cnt=`cat $MISMATCH`
if [ $miss_cnt -eq 0 ]; then
echo "Bad block is not exists. It is not necessary to repair." >&2
exit 2
fi
echo repair >$RAID_SYNC
;;
*) usage
;;
esac
exit 0
注)「¥」は実際には半角の「\」(バックスラッシュ)です。
RAIDアレイは/dev/md0 固定でして、例によって手抜きです(^^;)。これを"/usr/local/sbin/raid-check.sh" という名前のファイルに保存し、実行権をつけておきます。早速このスクリプトを使ってスクラビングを試してみました。作業は root で行います。
# cd /usr/local/sbin
# ./raid-check.sh start
# ./raid-check.sh status
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sdd1[5] sda1[4] sdb1[3] sdc1[6]
185054208 blocks super 1.2 level 5, 256k chunk, algorithm 2 [4/4] [UUUU]
[>....................] check = 0.1% (87120/61684736) finish=94.2min speed=10890K/sec
unused devices: <none>
No bad block.
# ./raid-check.sh detail
/dev/md0:
Version : 1.2
Creation Time : Sat Jul 30 11:24:03 2016
Raid Level : raid5
Array Size : 185054208 (176.48 GiB 189.50 GB)
Used Dev Size : 61684736 (58.83 GiB 63.17 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Sun Sep 4 21:06:56 2016
State : clean, checking
Active Devices : 4
Working Devices : 4
Failed Devices : 0
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 256K
Check Status : 2% complete
Name : RaspberryPi3:0 (local to host RaspberryPi3)
UUID : c26559b7:abb329b4:1960d0d5:7b9c8287
Events : 1087
Number Major Minor RaidDevice State
5 8 49 0 active sync /dev/sdd1
6 8 33 1 active sync /dev/sdc1
3 8 17 2 active sync /dev/sdb1
4 8 1 3 active sync /dev/sda1
|
スクラビングが始まりました。現在の使用量は27%ですが、94分ほどかかるようです。もし容量全部使いきったとしたら、単純計算で6時間くらいになるってことかな。この程度なら週に1回程度、深夜に行わせれば良いでしょう。
と言うことで、cronで月曜日の0時に起動するように仕込みました。(Jessieなので、systemdを使う手もありますが、どう考えてもcronの方が手軽。)
0 0 * * 1 /usr/local/sbin/raid-check.sh start
|
後は、スクラビングが終わった頃に、
# cat /sys/block/md0/md/mismatch_cnt
0
|
として、不良ブロック数が 0である事を確認するか、
# /usr/local/sbin/raid-check.sh status
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sdd1[5] sda1[4] sdb1[3] sdc1[6]
185054208 blocks super 1.2 level 5, 256k chunk, algorithm 2 [4/4] [UUUU]
unused devices: <none>
No bad block.
|
となっていればOKです。後々、スクラビングの結果をメールで送るような仕組みも作ってみますかね。
|