Tl; dr:RAID1アレイの1つのディスクの不良ブロックを修正するにはどうすればよいですか?
しかし、私がすでに試したことと私の方法で起こりうるエラーについては、この全体を読んでください。私はできるだけ詳細にしようとしました、そして私はいくつかのフィードバックを本当に望んでいます
これが私の状況です。mdadm
が管理するRAID1アレイに2TBの2台のディスク(同じモデル)がセットアップされています。約6か月前、SMARTがそれを報告したときに、最初の不良ブロックに気付きました。今日、私はもっと気づき、それを修正しようとしています。
このHOWTOページ は、不良ブロックを修正するために誰もがリンクする1つの記事のようですSMARTは報告しています。これは素晴らしいページですが、情報が豊富ですが、かなり時代遅れで、私の特定の設定には対応していません。
だから、それに取り掛かりましょう。これは私がやったことですが、動作していないようです。エラーがないか計算と方法を再確認してください。エラーを報告するディスクは/ dev/sdaです。
# smartctl -l selftest /dev/sda
smartctl 5.42 2011-10-20 r3458 [x86_64-linux-3.4.4-2-Arch] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net
=== START OF READ SMART DATA SECTION ===
SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Short offline Completed: read failure 90% 12169 3212761936
これにより、エラーがLBA 3212761936にあることがわかります。HOWTOに続いて、gdiskを使用して、後でブロック番号を決定するときに使用する開始セクターを見つけます(GPTをサポートしていないためfdiskを使用できないため)。
# gdisk -l /dev/sda
GPT fdisk (gdisk) version 0.8.5
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 3907029168 sectors, 1.8 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): CFB87C67-1993-4517-8301-76E16BBEA901
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 3907029134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 3907029134 1.8 TiB FD00 Linux RAID
tunefs
を使用すると、ブロックサイズは4096
になります。この情報とHOWTOからの計算を使用して、問題のブロックは((3212761936 - 2048) * 512) / 4096 = 401594986
であると結論付けます。
次にHOWTOはdebugfs
にブロックが使用されているかどうかを確認するように指示します(EXTファイルシステムが必要なため、RAIDデバイスを使用します。これは、最初は私が混乱させなかったので、混乱したコマンドの1つでした。/dev/sdaまたは/ dev/md0を使用する必要があるかどうかを確認します):
# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs: open /dev/md0
debugfs: testb 401594986
Block 401594986 not in use
したがって、ブロック401594986は空のスペースです。問題なく上書きできるはずです。ただし、それに書き込む前に、実際に読み取れないことを確認します。
# dd if=/dev/sda1 of=/dev/null bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000198887 s, 20.6 MB/s
ブロックが読み取れなかった場合、これが機能するとは思わないでしょう。ただし、そうです。ブロック番号に/dev/sda
、/dev/sda1
、/dev/sdb
、/dev/sdb1
、/dev/md0
、+-5を繰り返し使用して、不良ブロックの周辺を検索します。それはすべて動作します。私は肩をすくめて先に進み、書き込みと同期をコミットします(一方のディスクを変更し、もう一方のディスクを変更しないと問題が発生する可能性があるため、/ dev/md0を使用します。これにより、両方のディスクが不良ブロックを上書きします)。
# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000142366 s, 28.8 MB/s
# sync
不良ブロックに書き込むと、ディスクがブロックを良好なブロックに再割り当てすることになると思いますが、別のSMARTテストを実行すると、次のように異なります。
# 1 Short offline Completed: read failure 90% 12170 3212761936
スクエア1に戻ります。基本的に、RAID1アレイの1つのディスクの不良ブロックをどのように修正しますか?きっと何か正しく行ったことはないと思います...
あなたの時間と忍耐をありがとう。
私は長いSMARTテストを実行しましたが、同じLBAが不良として返されます(唯一の違いは、90%ではなく30%が残っているということです):
SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Extended offline Completed: read failure 30% 12180 3212761936
# 2 Short offline Completed: read failure 90% 12170 3212761936
次の出力で不良ブロックも使用しました。出力は奇妙で、形式が間違っているようですが、ブロックとして出力された数値をテストしようとしましたが、debugfsはエラーを出します
# badblocks -sv /dev/sda
Checking blocks 0 to 1953514583
Checking for bad blocks (read-only test): 1606380968ne, 3:57:08 elapsed. (0/0/0 errors)
1606380969ne, 3:57:39 elapsed. (1/0/0 errors)
1606380970ne, 3:58:11 elapsed. (2/0/0 errors)
1606380971ne, 3:58:43 elapsed. (3/0/0 errors)
done
Pass completed, 4 bad blocks found. (4/0/0 errors)
# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs: open /dev/md0
debugfs: testb 1606380968
Illegal block number passed to ext2fs_test_block_bitmap #1606380968 for block bitmap for /dev/md0
Block 1606380968 not in use
ここからどこに行くべきかわからない。 badblocks
は間違いなく何かを見つけましたが、表示された情報をどうするかわかりません...
その他のコマンドと情報。
もともとこれを入れ忘れたバカみたいです。これはSMART /dev/sda
の値です。Current_Pending_Sectorが1つあり、Offline_Uncorrectableが0つあります。
SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
1 Raw_Read_Error_Rate 0x002f 100 100 051 Pre-fail Always - 166
2 Throughput_Performance 0x0026 055 055 000 Old_age Always - 18345
3 Spin_Up_Time 0x0023 084 068 025 Pre-fail Always - 5078
4 Start_Stop_Count 0x0032 100 100 000 Old_age Always - 75
5 Reallocated_Sector_Ct 0x0033 252 252 010 Pre-fail Always - 0
7 Seek_Error_Rate 0x002e 252 252 051 Old_age Always - 0
8 Seek_Time_Performance 0x0024 252 252 015 Old_age Offline - 0
9 Power_On_Hours 0x0032 100 100 000 Old_age Always - 12224
10 Spin_Retry_Count 0x0032 252 252 051 Old_age Always - 0
11 Calibration_Retry_Count 0x0032 252 252 000 Old_age Always - 0
12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 75
181 Program_Fail_Cnt_Total 0x0022 100 100 000 Old_age Always - 1646911
191 G-Sense_Error_Rate 0x0022 100 100 000 Old_age Always - 12
192 Power-Off_Retract_Count 0x0022 252 252 000 Old_age Always - 0
194 Temperature_Celsius 0x0002 064 059 000 Old_age Always - 36 (Min/Max 22/41)
195 Hardware_ECC_Recovered 0x003a 100 100 000 Old_age Always - 0
196 Reallocated_Event_Count 0x0032 252 252 000 Old_age Always - 0
197 Current_Pending_Sector 0x0032 100 100 000 Old_age Always - 1
198 Offline_Uncorrectable 0x0030 252 100 000 Old_age Offline - 0
199 UDMA_CRC_Error_Count 0x0036 200 200 000 Old_age Always - 0
200 Multi_Zone_Error_Rate 0x002a 100 100 000 Old_age Always - 30
223 Load_Retry_Count 0x0032 252 252 000 Old_age Always - 0
225 Load_Cycle_Count 0x0032 100 100 000 Old_age Always - 77
# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Thu May 5 06:30:21 2011
Raid Level : raid1
Array Size : 1953512383 (1863.01 GiB 2000.40 GB)
Used Dev Size : 1953512383 (1863.01 GiB 2000.40 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Update Time : Tue Jul 3 22:15:51 2012
State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Name : server:0 (local to Host server)
UUID : e7ebaefd:e05c9d6e:3b558391:9b131afb
Events : 67889
Number Major Minor RaidDevice State
2 8 1 0 active sync /dev/sda1
1 8 17 1 active sync /dev/sdb1
答えの1つによれば、seek
をskip
とdd
に切り替えたようです。 HOWTOでシークを使用するため、シークを使用していました。このコマンドを使用すると、dd
がハングします。#dd if =/dev/sda1 of =/dev/null bs = 4096 count = 1 skip = 401594986
その周りのブロック(..84、..85、..87、..88)を使用すると問題なく動作するように見え、/ dev/sdb1をブロック401594986
と一緒に使用すると問題なく読み取ります(期待どおりにそのディスクはSMARTテスト)を通過しました。今、私が持っている質問は、この領域を上書きしてブロックを再割り当てする場合、/dev/sda1
または/dev/md0
を使用しますか? 1つのディスクに直接書き込み、他のディスクを更新しないことで、RAIDアレイに問題を発生させたくありません。
ブロックへの書き込みにより、直接ファイルシステムエラーが発生しました。私は問題をすばやく解決する答えを選びました:
# 1 Short offline Completed without error 00% 14211 -
# 2 Extended offline Completed: read failure 30% 12244 3212761936
助けてくれたみんなに感謝します。 =)
これらすべての「セクターを突く」という答えは、正直言って、非常識です。それらは(おそらく隠されている)ファイルシステムの破損のリスクがあります。データがすでになくなっている場合、そのディスクには唯一のコピーが格納されているため、それは妥当なことです。しかし、ミラーには完全に良いコピーがあります。
Mdraidでミラーをスクラブするだけです。不良セクターに気づき、自動的に書き換えます。
# echo 'check' > /sys/block/mdX/md/sync_action # use 'repair' instead for older kernels
適切なデバイスをそこに配置する必要があります(mdXではなくmd0など)。デフォルトでは配列全体を処理するため、これにはしばらく時間がかかります。新しい十分なカーネルでは、最初にセクター番号をsync_min/sync_maxに書き込んで、アレイの一部のみに制限することができます。
これは安全な操作です。あなたはあなたのすべてのmdraidデバイスでそれを行うことができます。実際、あなたはすべきすべてのmdraidデバイスで定期的にそれを行います。ディストリビューションには、これを処理するためのcronjobが同梱されている可能性があります。
しばらく前に、このスクリプトを書いて、システム上のすべてのRAIDデバイスを「修復」しました。これは、「修復」だけで不良セクタを修正できる古いカーネルバージョン用に作成されました。現在はチェックを行うだけで十分です(修復は新しいカーネルでも問題なく機能しますが、パリティの再コピー/再構築も行われます。これは、特にフラッシュドライブでは必ずしも望ましいことではありません)。
#!/bin/bash
save="$(tput sc)";
clear="$(tput rc)$(tput el)";
for sync in /sys/block/md*/md/sync_action; do
md="$(echo "$sync" | cut -d/ -f4)"
cmpl="/sys/block/$md/md/sync_completed"
# check current state and get it repairing.
read current < "$sync"
case "$current" in
idle)
echo 'repair' > "$sync"
true
;;
repair)
echo "WARNING: $md already repairing"
;;
check)
echo "WARNING: $md checking, aborting check and starting repair"
echo 'idle' > "$sync"
echo 'repair' > "$sync"
;;
*)
echo "ERROR: $md in unknown state $current. ABORT."
exit 1
;;
esac
echo -n "Repair $md...$save" >&2
read current < "$sync"
while [ "$current" != "idle" ]; do
read stat < "$cmpl"
echo -n "$clear $stat" >&2
sleep 1
read current < "$sync"
done
echo "$clear done." >&2;
done
for dev in /dev/sd?; do
echo "Starting offline data collection for $dev."
smartctl -t offline "$dev"
done
check
の代わりにrepair
を実行する場合は、この(テストされていない)最初のブロックが機能するはずです。
case "$current" in
idle)
echo 'check' > "$sync"
true
;;
repair|check)
echo "NOTE: $md $current already in progress."
;;
*)
echo "ERROR: $md in unknown state $current. ABORT."
exit 1
;;
esac
RAID1アレイでもほぼ同じ問題が発生しました。不良セクターは、パーティションの1つ(/ dev/sdb2のセクター16)の最初にありました。私は上記の指示に従いました:論理ブロック2がファイルシステムで使用されていないことを確認し、ddシークを取得して正しい方法でスキップするように注意して、1つのファイルシステムブロックをゼロにしました。
# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=2
これは何をしましたか?不良セクターは修正されませんでした。/dev/md0が/ dev/sdb2に直接マップしないため、これはRAIDデータオフセットを考慮する必要があります。これについては、以下で詳しく説明します。それが行ったことは、ファイルシステム上での小さいながらも壊滅的な可能性のある大混乱でした。/dev/md0の論理ブロック2には有用なファイルシステムメタデータが含まれており、/ dev/md0に書き込んで両方のコピーをクラップするまで、両方のディスクで正常でした。幸いなことに、e2fsck -y/dev/md0は、明らかなデータ損失を伴わずに(驚くべき量の出力を吐き出した後)問題を修正しました。教訓:debugfs icheckが「ブロックが見つかりません」と言っても、必ずしも対応するセクターが使用されていないことを意味するわけではありません。
データオフセットに戻ります。mdadmを使用して、次のようにオフセットを見つけます。
# mdadm --examine /dev/sdb2
/dev/sdb2:
Magic : a92b4efc
Version : 1.2
Feature Map : 0x0
Array UUID : ef7934b9:24696df9:b89ff03e:b4e5a05b
Name : XXXXXXXX
Creation Time : Sat Sep 1 01:20:22 2012
Raid Level : raid1
Raid Devices : 2
Avail Dev Size : 1953241856 (931.38 GiB 1000.06 GB)
Array Size : 976620736 (931.38 GiB 1000.06 GB)
Used Dev Size : 1953241472 (931.38 GiB 1000.06 GB)
Data Offset : 262144 sectors
Super Offset : 8 sectors
State : clean
Device UUID : f3b5d515:446d4225:c2191fa0:9a9847b8
Update Time : Thu Sep 6 12:11:24 2012
Checksum : abb47d8b - correct
Events : 54
Device Role : Active device 0
Array State : AA ('A' == active, '.' == missing)
この場合、データオフセットは512バイトの262144セクターです。/dev/md0からddし、それを131072Kのオフセットを持つrawパーティションのデータと比較すると、それらが一致していることがわかります。したがって、私の場合、/ dev/sdb2の論理ブロック2(セクター16〜23)はファイルシステムにさえありません。それらはRAIDスーパーブロックにあり、ここで読むことができます: https://raid.wiki.kernel.org/index.php/RAID_superblock_formats -バージョン1.2の場合、256バイト+アレイ内のデバイスごとに2バイト、すべて4096バイトで始まるため、私の場合、不良セクターは使用されませんでした。/dev/sdc2(RAID1アレイのもう半分)の対応するセクターはゼロなので、これを実行しても安全だと考えました。
# dd if=/dev/zero of=/dev/sdb2 bs=4096 count=1 seek=2
出来た!
Debianを実行している場合、おそらく/etc/cron.d/mdadmにジョブがあります。これは、毎月最初の日曜日に/usr/share/mdadm/checkarray --cron --all --idle --quiet
を実行します。修正できないハードウェアエラーが発生した場合は、手動で実行して、書き換えを迅速化してください。
dd
引数を混同しています。 seek
はoutputで指定されたオフセットにシークします。 inputのskip
ブロックが必要でした。
Sw-raid1があり、メンバーの1つに直接データを書き込んだ場合、レイドがすぐに破損します。 mdXの一部である場合は、sdaXまたはsdbXにデータを書き込まないでください。 mdXに書き込む場合は、両方のドライブにデータがコピーされます。mdXから読み取る場合は、いずれかのドライブからデータを読み取ります。