|
LS220DのRAIDメンテナンス機能について考える
参照:RAID - ArchWiki
この機能、ちょっと危ないのではなかろうか?
LS220DのRAIDメンテナンス機能。有効化しておくとデフォルトでは毎月一日の午前2時に動き出す。おそらくRAIDのデータスクラビング(誤りチェック・修正)をやっているのだと思うが、何をやっているのか気になったので少し調べてみた。
毎月一日の午前2時に動くということで cronを使っていると思われ、見ると "/etc/cron/crontabs/root"の中にそれらしい設定があった。
# cat /etc/cron/crontabs/root
10 4 * * * /etc/cron/cron.d/check_smart.sh
0 1 * * * /etc/cron/cron.d/diskmon_exec.sh
*/5 * * * * /etc/cron/cron.d/logrotate
8 4 * * * /etc/cron/cron.d/calib_time.sh
0 3 * * * /etc/cron/cron.d/date_to_lcd
15 2 1 * * /etc/cron/cron.d/hdd_check_standbydisk.sh
3 9 * * * /etc/cron/cron.d/ntpdate
0 0 * * * /etc/cron/cron.d/mailnotice.sh
0 2 1 * * /etc/cron/cron.d/mdscan start
26 22 * * * /etc/cron/cron.d/S40B_update_notifications.sh
|
一日午前2時に"/etc/cron/cron.d/mdscan"というスクリプトがキックされている。そのスクリプトを読んでみたところ、以下に対して"repair"を書き込む(echo)ことでスクラビングを行わせていた。
# ls -l /sys/block/*/md/sync_action
-rw-r--r-- 1 root root 4096 Sep 5 09:26 /sys/block/md0/md/sync_action
-rw-r--r-- 1 root root 4096 Sep 5 09:26 /sys/block/md1/md/sync_action
-rw-r--r-- 1 root root 4096 Sep 4 20:37 /sys/block/md101/md/sync_action
-rw-r--r-- 1 root root 4096 Sep 5 09:26 /sys/block/md2/md/sync_action
|
ここで気になるのが、RAID1 を構成している2台のHDD間でデータ不一致が見つかった場合どうなるのか?である。2台のHDDを使って冗長化しているのに、データの不一致があるのは問題だ。誤ったデータは正しいデータに修正したいところだが、RAIDシステムにどちらが正しいデータか判断できるのだろうか?
実は RAIDのデータスクラビングの一般的な注意事項として、以下のような気になる記述があったのだ。
ノート: ユーザーは /sys/block/md0/md/sync_action に repair を echo することもできますが、データにミスマッチが発生したとき、一貫性のために自動的に更新が行われるため、推奨されません。正しいパリティまたはデータブロックなのか (RAID1 の場合どちらのデータブロックなのか) 判断することができないのが危険です。この操作によって間違ったデータではなく正しいデータが選択されるかどうかは一か八かです。 |
思ったとおり、データ不一致があった場合に正しいデータに修正される確率は五分五分。よって"repair"は非推奨と言うことだ。スクラビングは"repair"ではなく "check"で行うようにし、不良セクタ(誤ったデータ)が検出されていないか、以下のようにチェックする。
# cat /sys/block/md*/md/mismatch_cnt
0
0
0
0
|
上記に0でないものがあれば、(S.M.A.R.T.情報等から)HDDにエラーや異常が発生していないか調べて、早期のデータバックアップとHDD交換するのが正しい対処だろう。
と言うことで、このまま毎月RAIDを"repair"させるのはよろしくないので、メンテナンススクリプト"/etc/cron/cron.d/mdscan"を修正しておこう。
#!/bin/sh
#
. /etc/melco/raidscan
. /etc/init.d/logtag
do_scan()
{
logger -t mdscan -p $LOGFACILITY "mdscan $1"
if [ $1 = start ]; then
if [ "$raidscan" != "on" ]; then
return
fi
for dev in /sys/block/*/md/sync_action
do
DIR=`dirname ${dev}`
DISKS=`cat ${DIR}/raid_disks`
LEVEL=`cat ${DIR}/level`
DEGRADED=`cat ${DIR}/degraded`
if [ ${DISKS} -eq 2 -a "${LEVEL}" = "raid1" -a ${DEGRADED} -eq 1 ] ; then
continue
fi
# echo repair > $dev
echo check > $dev
done
else
for dev in /sys/block/*/md/sync_action
do
echo idle > $dev
done
fi
}
case "$1" in
start)
case "$2" in
date)
TMP=`date +"%d"`
if [ "$schedule_no" = "1" ]; then
if [ "$TMP" -ge "1" ] && [ "$TMP" -le "7" ]; then
do_scan start
fi
elif [ "$schedule_no" = "2" ]; then
if [ "$TMP" -ge "8" ] && [ "$TMP" -le "14" ]; then
do_scan start
fi
elif [ "$schedule_no" = "3" ]; then
if [ "$TMP" -ge "15" ] && [ "$TMP" -le "21" ]; then
do_scan start
fi
elif [ "$schedule_no" = "4" ]; then
if [ "$TMP" -ge "21" ] && [ "$TMP" -le "28" ]; then
do_scan start
fi
elif [ "$schedule_no" = "13" ]; then
if [ "$TMP" -ge "1" ] && [ "$TMP" -le "7" ]; then
do_scan start
elif [ "$TMP" -ge "15" ] && [ "$TMP" -le "21" ]; then
do_scan start
fi
elif [ "$schedule_no" = "24" ]; then
if [ "$TMP" -ge "8" ] && [ "$TMP" -le "14" ]; then
do_scan start
elif [ "$TMP" -ge "21" ] && [ "$TMP" -le "28" ]; then
do_scan start
fi
fi
;;
* )
do_scan start
;;
esac
;;
stop)
do_scan stop
;;
esac
exit 0
|
幸いこのスクリプトは修正しても再起動で元に戻ってしまうことはないようだ。と言うことで動作確認。Webアクセスで、
とすると直ちに実行された。
# cat /proc/mdstat
Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]
md101 : active raid1 sda6[0] sdb6[2]
5844431680 blocks super 1.2 [2/2] [UU]
[>....................] check = 0.0% (1316544/5844431680) finish=3198.4min speed=30447K/sec
bitmap: 0/44 pages [0KB], 65536KB chunk
md0 : active raid1 sda1[0] sdb1[1]
999872 blocks [2/2] [UU]
bitmap: 0/1 pages [0KB], 65536KB chunk
md1 : active raid1 sda2[3] sdb2[2]
4995008 blocks super 1.2 [2/2] [UU]
bitmap: 1/1 pages [4KB], 65536KB chunk
md2 : active raid1 sda5[3] sdb5[2]
999424 blocks super 1.2 [2/2] [UU]
bitmap: 0/1 pages [0KB], 65536KB chunk
unused devices:
# cat /sys/block/md101/md/sync_action
check
# mdadm --detail /dev/md101
/dev/md101:
Version : 1.2
Creation Time : Tue Aug 26 14:19:11 2025
Raid Level : raid1
Array Size : 5844431680 (5573.68 GiB 5984.70 GB)
Used Dev Size : 5844431680 (5573.68 GiB 5984.70 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Intent Bitmap : Internal
Update Time : Thu Sep 4 20:26:59 2025
State : active, checking
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Check Status : 0% complete
Name : Mira:101 (local to host Mira)
UUID : 638d8a24:6bc080bf:1ad8b205:b4473386
Events : 12736
Number Major Minor RaidDevice State
0 8 6 0 active sync /dev/sda6
2 8 22 1 active sync /dev/sdb6
|
"repair"でなく、ちゃんと"check"で動いている。それにしても、やっぱり時間がかかる。制限速度を上げてみるが、
# echo 50000 >/proc/sys/dev/raid/speed_limit_min
# cat /proc/mdstat
Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]
md101 : active raid1 sda6[0] sdb6[2]
5844431680 blocks super 1.2 [2/2] [UU]
[>....................] check = 0.2% (12435072/5844431680) finish=1878.2min speed=51750K/sec
bitmap: 0/44 pages [0KB], 65536KB chunk
md0 : active raid1 sda1[0] sdb1[1]
999872 blocks [2/2] [UU]
bitmap: 0/1 pages [0KB], 65536KB chunk
md1 : active raid1 sda2[3] sdb2[2]
4995008 blocks super 1.2 [2/2] [UU]
bitmap: 1/1 pages [4KB], 65536KB chunk
md2 : active raid1 sda5[3] sdb5[2]
999424 blocks super 1.2 [2/2] [UU]
bitmap: 0/1 pages [0KB], 65536KB chunk
unused devices:
|
こんなものか。
スクラビングを停止させたい場合は、Webアクセスから止めても良いし、
# echo idle > /sys/block/md101/md/sync_action
# cat /sys/block/md101/md/sync_action
idle
|
とやって止めることもできる。
|