Linux-GPTを使用してRAID1アレイの不良ブロックを修復する


20

tl; dr:RAID1アレイの1つのディスクの不良ブロックを修正するにはどうすればよいですか?

しかし、私がすでに試したことと私のメソッドで起こりうるエラーについては、このすべてを読んでください。できる限り詳細になろうとしましたが、フィードバックを期待しています。

これが私の状況です:が管理するRAID1アレイに2TBのディスク(同じモデル)をセットアップしていmdadmます。約6か月前に、SMARTが報告した最初の不良ブロックに気付きました。今日、私はもっと気づき、今それを修正しようとしています。

このHOWTOページは、SMARTが報告している不良ブロックを修正するために誰もがリンクしている記事のようです。それは情報が満載の素晴らしいページですが、かなり古く、私の特定の設定に対応していません。ここに私の設定がどのように異なるかがあります:

  • 1つのディスクの代わりに、RAID1アレイで2つのディスクを使用しています。一方のディスクはエラーを報告し、もう一方のディスクは正常です。このHOWTOは1つのディスクのみを念頭に置いて作成されており、「ディスクデバイスまたはRAIDデバイスでこのコマンドを使用しますか?」
  • fdiskがサポートしていないGPTを使用しています。代わりにgdiskを使用していますが、必要な情報と同じ情報が得られることを期待しています

それでは、それを理解しましょう。これは私がやったことですが、機能していないようです。エラーの計算と方法を再確認してください。ディスクレポートエラーは/ 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デバイスを使用します。これは、最初は/ 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つのディスクの不良ブロックをどのように修正しますか?私は何かを正しくしていないと確信しています...

あなたの時間と忍耐に感謝します。


編集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

また、次の出力でbadblocksを使用しました。出力は奇妙でフォーマットが間違っているようですが、ブロックとして出力された数値をテストしようとしましたが、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間違いなく何かを見つけましたが、提示された情報をどうするかわかりません...


編集2

その他のコマンドと情報。

もともとこれを含めるのを忘れているばかみたいです。これはの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あたりとして:私がスイッチをしたと思われるseekskipのためにdd。HOWTOで使用されているシークを使用していました。このコマンドを使用するとdd、ハングします。#dd if = / dev / sda1 of = / dev / null bs = 4096 count = 1 skip = 401594986

その1つ(..84、.. 85、.. 87、.. 88)の周りのブロックを使用すると問題なく動作し、ブロック401594986読み取りで/ dev / sdb1を使用しても問題なく動作します(そのディスクがSMARTテストに合格したため、期待どおり) )。さて、私が持っている疑問は:ブロックを再割り当てするために、この領域の上に書くとき、私が使用するのです/dev/sda1/dev/md0?1つのディスクに直接書き込み、他のディスクを更新しないことで、RAIDアレイに問題を引き起こしたくありません。

編集3

ブロックに直接書き込むと、ファイルシステムエラーが発生しました。問題を迅速に解決する回答を選択しました。

# 1  Short offline       Completed without error       00%     14211         -
# 2  Extended offline    Completed: read failure       30%     12244         3212761936

助けてくれたみんなに感謝します。=)


ブロックを読み取ることができたため、破損していません。したがって、再割り当てされたセクターはありません。fsブロックの計算を確認しましたが、合法的なようです。不良ブロックの再割り当てを行ったときに、スマートショートテストで問題のあるブロックが正しく報告されないことがありました。その間、長いオフラインテストを実行してsmartctl -t long /dev/sda、最初のエラーのLBAが変化するかどうかを確認できます。
ジャリラーマネン

1
/sbin/badblocks -sv /dev/sdaディスクを確認してください。
ジッピー

両方の提案を行い、それに応じて投稿を更新しました。まだ立ち往生。= /
blitzmann

smartctlはゼロ以外のCurrent_Pending_Sectorカウントを報告しますか?Offline_Uncorrectableはゼロ以外ですか?
mgorven

質問にアレイのステータスを追加してくださいsudo mdadm -D /dev/md0
。– psusi

回答:


20

これらすべての「セクターを突く」答えは、率直に言って非常識です。ファイルシステムが破損する可能性があります(隠されている可能性があります)。そのディスクが唯一のコピーを保存しているため、データが既になくなっている場合、それは合理的です。しかし、ミラーには完全に良好なコピーがあります。

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デバイスのスクリプト

しばらく前に、システム上のすべての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

これありがとう。私は最近、最終的にそれを解決することを望んでこの問題に戻りました。/ dev / md0ブロックに書き込み、ファイルシステムの問題がありましたが、ありがたいことに、数時間の恐怖とリカバリシェルの起動後、データ損失のない修復がすべて行われました。最初にあなたの方法を試してみて、できればこれが保留中のセクターを取り除くことを願っています。=)
ブリッツマン

スクラブが完了したことをどのように確認できますか?ウィルcat /sys/block/mdX/md/sync_action行われたときに「アイドル」を読んで?
ジョンクラム14

はい@JonCram、あなたがして、ステータスを見ることができcat /proc/mdstat、スクリプトにそれを望んでいるか、場合/sys/…/sync_completed
derobert

5

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)

この場合、データオフセットは512144セクターの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

出来た!


ここにOP。この情報に感謝。この問題が発生したとき、私は跳躍して、/ dev / md0レベルのブロックをゼロにしました。悪い考えです。たまたまファイルシステムを破壊しました。ありがたいことに、とてつもなく長い時間をかけて修復した後、データ損失なしですべてが順調に見えました。しかし、最初のパニックで、私はこの投稿を完全に忘れました。私は最近、新しいアパートにサーバーを設置しました。これは、私のtodoリストにあるものの1つです。問題についての洞察に感謝します。これについてもう少し掘り下げてみると、OPを更新します。=)
ブリッツマン

2

debianを実行している場合、おそらく/etc/cron.d/mdadmにジョブがあります。これは/usr/share/mdadm/checkarray --cron --all --idle --quiet 、毎月最初の日曜日に実行されます。修正不能なハードウェアエラーが発生したときに手動で実行して、書き換えを促進します。


まあ、それを手動で実行するときは、おそらく中止したいでしょう--cron
デロバート

1

dd議論を混同しました。 出力でseek指定されたオフセットにシークさせます。入力をブロックしたい。skip


ありがとうございました!元の投稿を更新して、これからのデータを含めました。ここからブロックを修正する方法を教えていただければ、答えを提供すると思います。(ブロックに直接書き込む/dev/sda1/か、/dev/md0ブロックを上書きするために使用するかどうかはわかりません)=)
blitzmann

@ Ryan、md0への書き込みが進むべき道ですが、sda1も動作するはずです。
psusi

0

sw-raid1があり、メンバーの1つに直接データを書き込むと、すぐに破損したraidが発生します。mdXの一部である場合、sdaXまたはsdbXにデータを書き込まないでください。mdXに書き込むと、両方のドライブにデータがコピーされます。mdXから読み取ると、ドライブの1つからデータが読み取られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.