背景

背景

今天我检查了我的 raid6 阵列(使用 ext4 文件系统)并弹出了两条内核消息:

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

到目前为止,我不可能通过谷歌搜索任何有用的信息,因为我无法找到哪些(如果有)文件驻留在这些扇区中。

也许这更好地解释了我的要求:给定一个假设的实用程序,find-file我想调用find-file 2842495632并得到类似的答案/mnt/raid/this-file-has-a-mismatch

答案1

免责声明:
这可能都是错误的,我在这里很深,很容易犯错误,但很难验证你是否正确。我假设报告的扇区都是 512 字节。还有一些偏移可能是错误的。
我希望我的理解足够正确,但时间会证明一切。如果您发现错误,请纠正我!
所有命令都需要 root 权限才能运行。备份总是好的。

背景

我正在为与你同样的问题而苦苦挣扎。由于磁盘控制器卡损坏,RAID6 中的一半驱动器消失。不好。我现在有 48 个不匹配的 MD 扇区,想找出其中可能存储哪些文件。我的设置与你的类似,但我也混合了 LVM。

这个答案是针对我的设置的,因为我认为许多人实际上也使用 LVM,并且您没有提供设置的很多细节。这也是我唯一可以测试的。
在你的情况下,只需跳过 LVM 周围的部分。如果您对 md 数组进行了分区,您还必须找到文件系统的偏移量。无论哪种情况,它至少应该给你一些想法。

设置

存储设置如下所示:
6 个 SATA 驱动器上的 Mdraid RAID6 作为 /dev/md1。该阵列用作 LVM2 卷组“vg_arch”的 PV。 VG中有多个LV,其中之一是“lv_arch2”,格式为Ext4。

所以我们有: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→文件

左心室容量

我们已经到了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

我们可以看到PE属于LV/dev/vg_arch/lv_arch2并且没有偏移。如果它有偏移,我们必须考虑到这一点。

外线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

如果所有块都未使用,则完成。恭喜!如果没有,那么我们就得继续寻找受影响的文件。

下一步是找到正在使用该块的索引节点:

debugfs:  icheck 335555944
Block   Inode number
335555944   279577043

所以我们有一个受影响的 inode 279577043,让我们找到文件名:

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

最后,我们找到了受损坏的 mdadm 扇区影响的文件。那并不太难。 ;-)

要结束,请运行命令closequit退出debugfs

来源

很难找到有关此问题的信息,但以下是我最常使用的网站:

相关内容