Linux-GPT를 사용하여 RAID1 어레이에서 불량 블록 복구


20

tl; dr : RAID1 배열의 1 디스크에서 불량 블록을 수정하는 방법은 무엇입니까?

그러나 이미 시도한 내용과 내 방법에서 가능한 오류에 대해이 모든 것을 읽으십시오. 가능한 한 자세하게 설명하려고 노력하고 있으며, 피드백을 기대하고 있습니다.

이것은 내 상황입니다.에 의해 관리되는 RAID1 배열에 두 개의 2TB 디스크 (동일한 모델)가 설정되어 mdadm있습니다. 약 6 개월 전에 SMART가보고했을 때 첫 번째 불량 블록을 발견했습니다. 오늘 나는 더 많은 것을 알아 차리고 이제 고치려고합니다.

이 HOWTO 페이지 는 SMART가보고 한 불량 블록을 수정하기 위해 모든 사람이 링크하는 기사 인 것 같습니다. 정보가 가득한 멋진 페이지이지만 상당히 구식이며 내 특정 설정을 다루지 않습니다. 구성이 다른 방법은 다음과 같습니다.

  • 하나의 디스크 대신 RAID1 배열에 두 개의 디스크를 사용하고 있습니다. 한 디스크는 오류를보고하지만 다른 디스크는 정상입니다. 하우투는 하나의 디스크만을 염두에두고 작성되는데, '디스크 장치 나 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를 사용하여 나중에 블록 번호를 결정할 때 사용할 시작 섹터를 찾습니다 (fpt는 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 / 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 블록 번호로 불량 블록 주위를 검색 할 수 있습니다. 모두 작동합니다. 어깨를 으 and하고 쓰기와 동기화를 커밋합니다 (하나의 디스크를 수정하고 다른 디스크가 문제를 일으킬 수는 없기 때문에 / 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 :

동일한 LBA가 나쁜 것으로 반환하는 긴 SMART 테스트를 시도했습니다 (단, 차이점은 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_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

답변 중 하나에 따라 경찰 : 그것은 것 같다 나는 스위치를했다 seekskip위해를 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? 한 디스크에 직접 쓰거나 다른 디스크 업데이트를하지 않고 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가 변경되는지 확인할 수 있습니다.
Jari Laamanen

1
시도 /sbin/badblocks -sv /dev/sda디스크를 확인합니다.
jippie

나는 두 가지 제안을 모두했고 그에 따라 게시물을 업데이트했습니다. 여전히 붙어있다. = /
blitzmann

smartctl이 0이 아닌 Current_Pending_Sector 카운트를보고합니까? Offline_Uncorrectable이 0이 아닌가?
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 블록에 쓰고 파일 시스템 문제가 있었지만 몇 시간 동안 테러와 복구 셸로 부팅 한 후 데이터 손실없이 복구되었습니다. 나는 당신의 방법을 먼저 시도하고 희망적으로 이것이 보류중인 부문을 제거 할 것입니다. =)
blitzmann 2018 년

스크럽이 완료된 시점을 어떻게 알 수 있습니까? 윌 cat /sys/block/mdX/md/sync_action완료되면 '유휴'를 읽어?
Jon Cram

@JonCram 예, cat /proc/mdstat스크립트를 작성하거나 스크립트를 작성하려는 경우 상태를 볼 수 있습니다 ./sys/…/sync_completed
derobert

5

RAID1 어레이와 거의 같은 문제가 있습니다. 불량 섹터는 파티션 중 하나의 시작 부분 인 / dev / sdb2의 섹터 16에 있습니다. 위의 지침을 따랐습니다. 파일 시스템에서 논리 블록 2를 사용하고 있지 않은지 확인하고 dd seek 및 올바른 방법으로 건너 뛰도록주의하고 1 파일 시스템 블록을 0으로 제거했습니다.

# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=2

이것은 무엇을 했습니까? 불량 섹터를 수정하지 않았습니다. 이것은 / dev / md0이 / dev / sdb2에 직접 매핑되지 않기 때문에 RAID DATA OFFSET을 고려해야한다는 것입니다. 이에 대한 자세한 내용은 아래를 참조하십시오. 그것은 내 파일 시스템에 작지만 잠재적으로 파괴적인 똥이었습니다. / dev / md0의 논리 블록 2에 유용한 파일 시스템 메타 데이터가 포함되어 있고 / dev / md0에 기록하여 복사본 을 모두 잘릴 때까지 두 디스크 모두에 문제가 없었습니다 . 운 좋게도 e2fsck -y / dev / md0은 명백한 데이터 손실없이 문제를 해결했습니다 (경량의 출력을 분출 한 후). 교훈 : icheck debugfs에 'block not found'가 있다고해서 반드시 해당 섹터가 사용되지 않는다는 의미는 아닙니다.

데이터 오프셋으로 돌아 가기 : 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 인 원시 파티션의 데이터와 비교하면 일치하는 것을 알 수 있습니다. 따라서 필자의 경우 / dev / sdb2의 논리적 블록 2 (섹터 16-23)는 파일 시스템에도 없습니다. 그들은 당신이 여기에 대해 읽을 수있는 RAID 수퍼 블록에 위치 : https://raid.wiki.kernel.org/index.php/RAID_superblock_formats - 배열의 기기 당 1.2 버전에 대한, 그것은 256 바이트로 구성이 + 2 바이트 , 모두 4096 바이트로 시작하므로 제 경우에는 불량 섹터가 사용되지 않았습니다. / dev / sdc2 (RAID1 어레이의 다른 절반)의 해당 섹터는 0 이므로이 작업을 수행하는 것이 안전하다고 생각했습니다.

# dd if=/dev/zero of=/dev/sdb2 bs=4096 count=1 seek=2

효과가 있었다!


여기 OP 정보 감사합니다. 이 문제가 나에게 일어 났을 때, 나는 도약을했고 / dev / md0 레벨에서 블록을 제로화했다. 파일 시스템을 폐기하는 것처럼 나쁜 생각. 고맙게도 수리 시간이 지난 후에도 데이터 손실없이 모두 잘 보였습니다. 그러나 초기 공황 으로이 게시물에 대해 완전히 잊었습니다. 최근에 새 아파트에 서버를 설치했는데이 작업이 다시 할 일 목록에있는 것 중 하나입니다. 문제에 대한 통찰력에 감사드립니다. 이것에 조금 더 파고들 때 OP를 업데이트 할 것입니다. =)
blitzmann

2

데비안을 실행하면 /etc/cron.d/mdadm에 작업이있을 가능성이 높습니다. 이 실행됩니다 /usr/share/mdadm/checkarray --cron --all --idle --quiet 매월 첫 번째 일요일을. 다시 쓰기를 촉진하기 위해 수정할 수없는 하드웨어 오류가 발생하면 수동으로 실행하십시오.


글쎄, 수동으로 실행할 때 아마 떠나고 싶을 것입니다 --cron.
derobert

1

당신은 당신의 dd주장을 섞었습니다 . 출력seek 에서 지정된 오프셋을 찾도록합니다 . 입력 을 차단 하려고했습니다 .skip


고맙습니다! 이 게시물의 데이터를 포함하도록 원래 게시물을 업데이트했습니다. 여기서 블록을 고치는 방법을 말해 주시면 답변을 드리겠습니다. (내가 직접 작성해야하는 경우 확실하지 오전 /dev/sda1/또는 사용 /dev/md0덮어 쓰기 블록) =)
blitzmann

sda1도 작동해야하지만 @Ryan, md0에 쓰는 것이 좋습니다.
psusi

0

sw-raid1이 있고 구성원 중 하나에 직접 데이터를 쓰면 즉시 급습이 손상됩니다. mdX의 일부인 경우 sdaX 또는 sdbX에 데이터를 쓰지 마십시오. mdX에 쓰면 두 드라이브 모두에 ​​데이터가 복사되고 mdX에서 읽으면 드라이브 중 하나에서 데이터를 읽습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.