今天我检查了我的 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 恢复的信息,并在尝试恢复时使用覆盖,以免破坏数据。摧毁这一切是非常容易的。
- https://raid.wiki.kernel.org/index.php/Recovering_a_failed_software_RAID
- https://raid.wiki.kernel.org/index.php/Irreversible_mdadm_failure_recovery
- https://raid.wiki.kernel.org/index.php/Linux_Raid#When_Things_Go_Wrogn
我假设您已经组装好阵列并正在工作,至少在只读模式下。我在测试时使用了覆盖,因此我没有错误地将任何内容写入真实数组。本指南仅需要只读访问权限。
部门狩猎
首先,我们从内核获得的扇区号是 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 = 2684447504
LVM 中的扇区开始,到 结束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 扇区影响的文件。那并不太难。 ;-)
要结束,请运行命令close
并quit
退出debugfs
。
来源
很难找到有关此问题的信息,但以下是我最常使用的网站:
- https://raid.wiki.kernel.org/index.php/Recovering_a_failed_software_RAID- Mdadm 恢复
- https://strugglers.net/~andy/blog/2021/07/24/resolving-a-sector-offset-to-a-logic-volume/- 解决部门偏移问题
- https://wiki.archlinux.org/title/Identify_damaging_files- 文件系统调试
https://serverfault.com/questions/315700/how-to-define-which-file-inode-occupies-a-given-sector - md raid5:将 md 内部扇区号转换为偏移量- 部门翻译
- https://raid.wiki.kernel.org/index.php/RAID_superblock_formats- RAID 超级块格式
- md raid5:将 md 内部扇区号转换为偏移量- 将 MD 内部扇区号转换为偏移量