배경

배경

오늘 나는 raid6 배열(ext4 파일 시스템 사용)을 확인했는데 두 개의 커널 메시지가 나타났습니다.

mismatch sector in range 2842495632-2842495640
mismatch sector in range 2927793488-2927793496

지금까지는 이 섹터에 어떤 파일(있는 경우)이 있는지 찾을 수 없기 때문에 유용한 정보를 Google에서 검색하는 것이 불가능했습니다.

어쩌면 이것이 내 요구 사항을 더 잘 설명할 수도 있습니다. 가상의 유용성이 주어지면 전화를 걸어 비슷한 답변을 받고 find-file싶습니다 .find-file 2842495632/mnt/raid/this-file-has-a-mismatch

답변1

면책 조항:
이것은 모두 틀릴 수 있습니다. 저는 여기에 매우 깊이 관여하고 실수하기 쉽지만 당신이 맞는지 확인하기는 어렵습니다. 보고된 섹터는 모두 512바이트라고 가정합니다. 잘못될 수 있는 오프셋도 있습니다.
내 이해가 충분히 정확하기를 바라지만, 시간이 말해줄 것입니다. 오류를 발견하시면 정정해주세요!
모든 명령을 실행하려면 루트 권한이 필요합니다. 항상 백업을 해 두는 것이 좋습니다.

배경

나는 당신과 같은 문제로 어려움을 겪고 있습니다. 불량 디스크 컨트롤러 카드로 인해 RAID6의 드라이브 중 절반이 사라졌습니다. 안좋다. 이제 일치하지 않는 MD 섹터가 48개 있고 여기에 어떤 파일이 저장되어 있는지 알아보고 싶습니다. 내 설정은 귀하의 설정과 유사하지만 LVM에서도 혼합합니다.

많은 사람들이 실제로 LVM을 사용하고 있고 설정에 대한 세부 정보를 많이 제공하지 않았기 때문에 이 답변은 내 설정에만 해당됩니다. 이것은 또한 내가 테스트할 수 있는 유일한 것입니다.
귀하의 경우에는 LVM 주변 부분을 건너 뛰십시오. md 배열을 분할한 경우 파일 시스템 오프셋도 찾아야 합니다. 어떤 경우이든 최소한 몇 가지 아이디어를 제공해야 합니다.

설정

스토리지 설정은 다음과 같습니다:
6개 SATA 드라이브의 Mdroid RAID6(/dev/md1). 이 어레이는 LVM2 볼륨 그룹 "vg_arch"의 PV로 사용됩니다. VG에는 여러 개의 LV가 있으며 그 중 하나는 Ext4 형식의 "lv_arch2"입니다.

따라서 HDD→MD→LVM→Ext4가 있습니다.

질문

mdraid 배열( )을 검사한 후 /usr/share/mdadm/checkarray -a /dev/md1다음과 같은 줄을 발견했습니다 /var/log/syslog.

Jan  4 03:28:28 orion kernel: [36199.659889] md1: mismatch sector in range 2684449552-2684449560
Jan  4 03:28:28 orion kernel: [36199.659897] md1: mismatch sector in range 2684449560-2684449568
Jan  4 03:28:28 orion kernel: [36199.659901] md1: mismatch sector in range 2684449568-2684449576
Jan  4 03:28:28 orion kernel: [36199.659904] md1: mismatch sector in range 2684449576-2684449584
Jan  4 03:28:28 orion kernel: [36199.659921] md1: mismatch sector in range 2684449584-2684449592
Jan  4 03:28:28 orion kernel: [36199.659925] md1: mismatch sector in range 2684449592-2684449600

여기서 문제는 RAID 어레이의 일부 블록이 손상되어 데이터를 신뢰할 수 없다는 것입니다. 이에 대한 다양한 이유는 거의 무한하지만 섹터가 불량하므로 이제 거기에 파일이 저장되어 있는지, 그렇다면 어떤 파일인지 알아내야 합니다.
내 경우에는 배열이 50/50으로 분할되어 mdraid가 어떤 데이터를 사용할지 알 수 없었습니다.

불량 섹터의 범위는 2684449552 – 2684449600, 총 48개입니다.

데이터 손상을 방지하려면 먼저 RAID 복구에 대해 읽어보고 복구를 시도할 때 덮어쓰기를 사용하는 것이 좋습니다. 모든 것을 파괴하는 것은 매우 쉽습니다.

적어도 읽기 전용 모드에서 어레이를 조립하고 작동한다고 가정합니다. 테스트할 때 재정의를 사용하여 실수로 실제 배열에 아무것도 쓰지 않았습니다. 이 가이드에는 읽기 전용 액세스만 필요합니다.

부문 사냥

첫째, 커널에서 얻은 섹터 번호는 md 배열의 섹터입니다(적어도 내 가정은 그렇습니다). 이는 스토리지 스택의 낮은 수준(파티션 오프셋 등)에 대해 생각할 필요가 없으므로 작업이 좀 더 쉬워지기 때문에 좋습니다.

우리가 따라야 할 경로는 다음과 같습니다: HDD→MD→LVM→Ext4→File

좌심실 용적

MD 레벨에 도달했으니 이제 LVM을 살펴봐야 합니다.

LVM 스택의 맨 아래는 PV(물리적 볼륨)입니다. 이는 여러 익스텐트로 나누어지며, 하나 이상의 익스텐트는 논리 볼륨(LV)을 형성합니다. 물리적 볼륨은 기본 장치일 뿐이므로 이 경우에는 /dev/md1.

PV의 데이터는 섹터 0에서 직접 시작되지 않지만 오프셋이 있습니다. 첫 번째 섹터는 LVM 메타데이터에 사용됩니다. 먼저 PV 시작 범위가 얼마나 멀리 떨어져 있는지 파악해야 합니다.

# pvs --noheadings -o pe_start --units s /dev/md1
2048S

데이터는 PV의 섹터 2048에서 시작됩니다. 문제의 섹터는 2684449552-2048 = 2684447504LVM 의 섹터로 시작하고 끝납니다 2684449600-2048 = 335555944.

다음으로 LVM 범위가 얼마나 큰지 알아야 합니다.

# pvdisplay --units s /dev/md1 | grep 'PE Size'
PE Size               8192 Se

각 LVM 범위에는 8192개의 섹터가 있습니다.

이제 문제가 시작된 정도를 계산할 수 있습니다.2684447504/8192 = 327691,345703125 extents

해당 부문이 정확한 PE 경계에 있지 않기 때문에 이는 분수입니다. 나머지는 PE의 섹터 오프셋을 제공합니다. 0,345703125*8192 = +2832 sectors

다음 단계는 PE 327691을 사용하는 LV를 찾는 것입니다.

# pvdisplay --maps /dev/md1 | grep -A1 'Physical extent'
  Physical extent 0 to 2621439:
    Logical volume  /dev/vg_arch/lv_arch2
--
  Physical extent 2621440 to 3801087:
    Logical volume  /dev/vg_arch/lv_test

/dev/vg_arch/lv_arch2PE가 LV에 속 하고 오프셋이 없음을 알 수 있습니다 . 상쇄된 경우 이를 고려해야 합니다.

외곽선 4

이제 파일 시스템 수준으로 진행하기에 충분한 정보가 있습니다. 먼저 우리가 사용하고 있는 섹터/블록 크기를 알아야 합니다.

# fdisk -u -l /dev/md1
Disk /dev/md1: 14.52 TiB, 15959456743424 bytes, 31170813952 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 1048576 bytes / 4194304 bytes

md 배열은 512바이트 섹터를 사용합니다. (이것이 맞는지는 잘 모르겠습니다. 기본적으로 커널이 오류를 보고할 때 동일한 섹터 크기를 사용한다고 가정했습니다.)

Ext4 블록 크기를 얻으려면:

# tune2fs -l /dev/vg_arch/lv_arch2 | grep Block
Block count:              2684354560
Block size:               4096

파일 시스템은 4KiB 블록을 사용하며 이는 블록당 8섹터에 해당합니다.

이제 mdadm 섹터 번호는 동일하지 않기 때문에 Ext4 블록 번호로 변환해야 합니다. 이를 위해 다음 공식을 사용할 수 있습니다.

(mdadm sector number) / ((filesystem block size) / (mdadm sector size)) = Ext4 block number

이 경우에는 다음이 있습니다.

2684447504 / (4096 / 512) = 335555938 (start)
2684447552 / (4096 / 512) = 335555944 (stop)

따라서 Ext4 파일 시스템에서 문제가 되는 블록 범위는 335555938~335555944입니다.

서류 확인

이제 블록 번호가 있으면 거기에 저장된 파일을 찾아볼 수 있습니다. 이는 를 사용하여 수행할 수 있습니다 debugfs.

# debugfs
debugfs:

debugfs그런 다음 콘솔 에서 open 명령을 사용하여 파일 시스템을 엽니다(아직 설치되지 않았어야 함).

debugfs:  open /dev/vg_arch/lv_arch2

대용량 파일 시스템이 있는 경우 이 작업에 다소 시간이 걸릴 수 있습니다.

이제 이러한 블록이 사용되는지 테스트를 시작할 수 있습니다. 운이 좋으면 불량 블록은 어떤 파일에서도 사용되지 않습니다. 그것을 테스트하는 데 사용하십시오 testb blocknumber.

debugfs:  testb 335555938
Block 335555938 not in use

가지고 있는 모든 불량 블록에 대해 이 명령을 반복하고 다음과 같이 사용된 모든 불량 블록을 기록합니다.

debugfs:  testb 335555944
Block 335555944 marked in use

모든 블록이 사용되지 않으면 완료됩니다. 축하해요! 그렇지 않은 경우 영향을 받은 파일을 계속 찾아야 합니다.

다음 단계는 블록을 사용하는 inode를 찾는 것입니다.

debugfs:  icheck 335555944
Block   Inode number
335555944   279577043

따라서 영향을 받은 inode 279577043이 있습니다. 파일 이름을 찾아보겠습니다.

debugfs:  ncheck 279577043
Inode   Pathname
279577043   /my_files/file.dat

마지막으로 손상된 mdadm 섹터의 영향을 받는 파일을 발견했습니다. 별로 어렵지 않습니다. ;-)

종료하려면 명령을 실행 close하고 quit종료하십시오 debugfs.

원천

이 문제에 대한 정보를 찾기는 어렵지만 제가 가장 많이 사용하는 사이트는 다음과 같습니다.

관련 정보