Linux - GPTを使用したRAID1アレイの不良ブロックの回復

Linux - GPTを使用したRAID1アレイの不良ブロックの回復

重要な要約:RAID1アレイの1つのディスク上の不良ブロックをどのように修正しますか?

しかし、私が試したことと私のアプローチにどのような問題があるのか​​を理解するには、記事全体を読んでください。できるだけ詳しく説明しようと頑張り、フィードバックを聞きたいです。

私の状況は次のとおりです。で設定された2つの2TBディスク(同じモデル)がありますmdadm。 SMARTが報告したとき、約6ヶ月前に最初の不良ブロックが見つかりました。私は今日それをもっと悟り、今努力しています。

このガイドページSMARTが報告した不良ブロックを修正する方法について誰もがリンクする記事があるようです。これは情報でいっぱいの素晴らしいページですが、かなり古く、私の特定の設定をカバーしていません。私の構成の違いは次のとおりです。

  • 私はRAID1アレイで1つではなく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を使用しました(fdiskはGPTをサポートしていないため使用できませんでした)。

# 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を使用する必要があるかどうかわからなかったため、混乱したコマンドの1つです)。 /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-5/dev/sda1を繰り返し使用します。すべて動作します。私は肩をすくめて書き込みと同期を続けました。 (あるディスクを修正すると、他のディスクは修正しないと問題が発生し、両方のディスクが不良ブロックを上書きできると思ったので、/dev/md0を使用しました。)/dev/sdb/dev/sdb1/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

また、次の出力に不良ブロックを使用しました。出力が奇妙でフォーマットが間違っているようです。数値出力をチャンクでテストしましたが、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_Un 変更可能が 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でfindを使用しているのでfindを使用しています。このコマンドを使用するとdd中断が発生します。 # dd if=/dev/sda1 of=/dev/null bs=4096 count=1skip=401594986

その周辺のブロック(..84、..85、..87、..88)を使用すると正常に動作するようで、/dev/sdb1とブロック401594986読み取りを使用することも大丈夫です(予想通り、ディスクはSMARTテストを行います通過しました)。 。今私の質問は次のとおり/dev/sda1です/dev/md0。別のディスクを更新せずにディスクに直接書き込むことで、RAIDアレイに問題を引き起こしたくありません。

編集3

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

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

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

ベストアンサー1

これらすべての「産業刺激」の答えは正直に言うべきではありません。 (隠されている可能性がある)ファイルシステムが破損する危険性があります。ディスクに唯一のコピーが保存されているため、データが消えた場合、これは合理的です。しかし、鏡には完璧なコピーがあります。

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

おすすめ記事