![10TB ext3 RAID 6 的 fsck 存在重大问题(内存分配失败等)](https://linux22.com/image/613638/10TB%20ext3%20RAID%206%20%E7%9A%84%20fsck%20%E5%AD%98%E5%9C%A8%E9%87%8D%E5%A4%A7%E9%97%AE%E9%A2%98%EF%BC%88%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E5%A4%B1%E8%B4%A5%E7%AD%89%EF%BC%89.png)
我最近将第 7 个 2TB 驱动器添加到 Linux md 软件 RAID 6 设置中。在 md 将阵列从 6 个驱动器重塑为 7 个驱动器(从 8 个驱动器重塑为 10TB)后,我仍然能够毫无问题地挂载文件系统。为了准备 resize2fs,我卸载了分区并运行fsck -Cfyv
,结果出现了数以百万计的随机错误。以下是一段简短的摘录:
Pass 1: Checking inodes, blocks, and sizes
Inode 4193823 is too big. Truncate? yes
Block #1 (748971705) causes symlink to be too big. CLEARED.
Block #2 (1076864997) causes symlink to be too big. CLEARED.
Block #3 (172764063) causes symlink to be too big. CLEARED.
...
Inode 4271831 has a extra size (39949) which is invalid Fix? yes
Inode 4271831 is in use, but has dtime set. Fix? yes
Inode 4271831 has imagic flag set. Clear? yes
Inode 4271831 has a extra size (8723) which is invalid Fix? yes
Inode 4271831 has EXTENTS_FL flag set on filesystem without extents support. Clear? yes
...
Inode 4427371 has compression flag set on filesystem without compression support. Clear? yes
Inode 4427371 has a bad extended attribute block 1242363527. Clear? yes
Inode 4427371 has INDEX_FL flag set but is not a directory. Clear HTree index? yes
Inode 4427371, i_size is 7582975773853056983, should be 0. Fix? yes
...
Inode 4556567, i_blocks is 5120, should be 5184. Fix? yes
Inode 4566900, i_blocks is 5160, should be 5200. Fix? yes
...
Inode 5628285 has illegal block(s). Clear? yes
Illegal block #0 (4216391480) in inode 5628285. CLEARED.
Illegal block #1 (2738385218) in inode 5628285. CLEARED.
Illegal block #2 (2576491528) in inode 5628285. CLEARED.
...
Illegal indirect block (2281966716) in inode 5628285. CLEARED.
Illegal double indirect block (2578476333) in inode 5628285. CLEARED.
Illegal block #477119515 (3531691799) in inode 5628285. CLEARED.
压缩?扩展?我从来没有在这台机器附近安装过 ext4!
现在,问题是 fsck 不断死机并显示以下错误消息:
Error storing directory block information (inode=5628285, block=0, num=316775570): Memory allocation failed
起初我可以简单地重新运行 fsck,它会在不同的 inode 上死亡,但现在它已稳定在 5628285,我无法让它超越这个位置。
我花了几天时间尝试寻找解决此问题的方法,并找到了以下 3 个“解决方案”:
- 使用 64 位 Linux。
/proc/cpuinfo
包含lm
作为处理器之一flags
,getconf LONG_BIT
返回64
并uname -a
有以下说明:Linux <servername> 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
。应该一切都很好,不是吗? - 将
[scratch_files]
/添加directory = /var/cache/e2fsck
到/etc/e2fsck.conf
。这样做之后,每次我重新运行 fsck 时,它都会向目录中添加另一个 500K*-dirinfo-*
和一个 8M 的*-icount-*
文件/var/cache/e2fsck
。所以这似乎也达到了预期的效果。 - 为机器添加更多内存或交换空间。12GB 的 RAM 和 32GB 的交换分区应该足够了,不是吗?
不用说:没有任何帮助,否则我就不会在这里写了。
当然,现在驱动器被标记为坏了,我无法再安装它了。那么,截至目前,我因磁盘检查而丢失了 8TB 的数据?!?!?
这让我有三个问题:
- 除了花一个月的时间学习 ext3 磁盘格式,然后尝试用十六进制编辑器手动修复它之外,我还能做什么来修复这个驱动器(记住,在我运行 fsck 之前一切都很好!)???
- 对于像 ext3 这样流行的文件系统来说,像 fsck 这样关键的任务怎么还会有这样的问题呢??? 尤其是 ext3 已经有十多年的历史了。
- 有没有一种可以替代 ext3 且不存在这些基本可靠性问题的方案?也许是 jfs?
(我现在在 64 位 Debian Wheezy 7.1 上使用 e2fsck 1.42.5,但在 32 位 Debian Squeeze 上使用早期版本时也遇到同样的问题)
答案1
只需重建阵列并从备份中恢复数据即可。RAID 的重点是尽量减少停机时间。通过乱搞并尝试修复此类问题,您只会增加停机时间,从而违背 RAID 的整个目的。RAID 不能防止数据丢失,而是防止停机。
答案2
fsck
经过更多尝试后,我发现了一些补救措施:
防止出现“内存分配失败”错误
fsck
似乎存在内存泄漏的重大问题。如果它在存在某些问题(真实或虚构)的文件系统上运行,它将逐个“修复”这些问题(请参阅原始问题中的屏幕转储)。在这样做的过程中,它会消耗越来越多的内存(也许会保留更改日志?)。几乎没有限制。但是,fsck
可以随时取消(Ctrl-C)并重新启动。在这种情况下,它将从中断的地方继续,但其内存使用量将重置为几乎为零(暂时)。
考虑到这一点,需要做三件事:
- 使用 64 位 Linux(似乎对如何
fsck
使用可用内存有所区别) - 添加一个超大的交换分区(我用了 256GB,
fsck
运行了大约 12 个小时) - 频繁中止并重新启动 fsck(频率取决于交换分区的大小)
注意:我不知道取消并重新启动是否fsck
会带来任何其他危险(可能会),但它似乎对我有用。
如果发生“内存分配失败”错误,处理由此造成的损害(重要!)
fsck
以最糟糕的方式处理Memory allocation failed
错误:破坏完好无损的数据。我不确定为什么,但我的猜测是它将一些保存在内存中的内容最终写入磁盘,而这些内容(由于错误)同时被损坏了。
就我而言,最明显的问题是,当我fsck
在错误发生后重新启动时,它有时会报告损坏的超级块。问题是:我不知道如何超级块损坏了,尤其是在没有报告损坏的情况下。也许,如果在错误发生后重新启动,它会使用损坏的超级块中发现的不正确的驱动器元数据进行所有进一步的检查,最终修复实际上不存在的“问题”,从而破坏过程中的好数据。
因此,如果fsck
曾经因错误而死机Memory allocation failed
,需要使用-b
参数重新启动,以使用(希望)未因错误而损坏的备份超级块。可以使用 找到备份超级块的位置mke2fs -n /dev/...
。
因为我不知道如果fsck
在选择了备份超级块的情况下死机会发生什么,所以我通常fsdk
在到达时立即中止Pass 1: Checking inodes, blocks, and sizes
,然后重新启动它-b
,此时它会启动而不会抱怨超级块损坏。也就是说,它似乎做的第一件事fsck -b
就是恢复主超级块。
现在我们一直在等待的是:
如何在不让 fsck 运行完成的情况下挂载文件系统
这是我偶然发现的:事实证明,在运行fsck -b
并中止它之后,一旦它打印Pass 1: Checking inodes, blocks, and sizes
(在发现任何错误之前),文件系统就会处于可安装状态(耶!我几乎恢复了所有数据!)。
(注意:可能还有其他使用方法mount -o force
,但就我的情况而言不需要。)
如何避免所有这些问题
似乎有两种方法:
- 使用 ext3,但要保留最新的备份。然后,经常
fsck
使用参数运行-N
。如果显示任何问题,删除整个 fs 并从备份中恢复所有内容。由于在这种情况下,人们会非常依赖备份,因此我建议保留备份的备份。此外,使用复制工具,以某种方式确保恢复过程中不会产生随机错误(处理 TB 级数据时,一万亿次读写操作的 MTBF 很小)。确保也为由此产生的停机时间做好计划,因为多 TB 恢复可能需要一段时间…… - 我的建议:不要使用 ext3!fs-design 和相关工具(此处
fsck
)还不够强大,无法用于实际生产(目前还不够?)。fsck
处理内存错误的方式以及首先发生错误的事实在我看来是不可接受的。从现在开始我将尝试 xfs,但还没有足够的经验来判断它是否更好。
答案3
不幸的是,我无法“添加评论”,但不得不在这里附和并感谢 Op。我遇到了 RAID6 故障,并手动组装了 8 个驱动器中的 6 个,事件计数非常接近。但是我无法mount
组装阵列。
看来我需要使用备用超级块。运行fsck -b <location> ...
最终因内存不足而终止,这让我想到了这个主题/问题。
简而言之,使用fsck -b <location>...
然后执行ctrl+c
允许我安装我的阵列并恢复我的文件。
谢谢!