在大型文件系统上运行 fsck 时内存不足

在大型文件系统上运行 fsck 时内存不足

我照看一台旧的 Debian Linux 机器(运行 etch),它只有 512 MB 的 RAM,但连接了大量的外部存储。一个 ext3 文件系统大小为 2.7 TB,fsck 无法检查它,因为它内存不足,并出现如下错误:

   分配目录块数组时出错:内存分配失败
   e2fsck:已中止

我已经添加了一个 4 GB 的交换分区,但仍然没有完成,但这是一个 32 位内核,所以我不认为添加更多分区会有帮助。

除了启动 64 位内核之外,还有其他方法可以让 fsck 完成检查吗?

答案1

64 位内核和大量 RAM 将使 fsck 能够快速顺利地完成。另外,e2fsck 中现在有一个选项,它会告诉它将所有中间结果存储在目录中,而不是 RAM 中,这非常有帮助。使用/etc/e2fsck.conf以下内容创建:

[scratch_files]
directory = /var/cache/e2fsck

(并且,显然,确保该目录存在,并且位于具有几 GB 可用空间的分区上)。e2fsck 将运行很长时间,但至少它会完成。

当然,这不适用于根文件系统 (root FS),但是如果您有交换,那么无论如何您都已经可以挂载根文件系统 (root FS)。

答案2

我最终尝试了 womble 的建议;如果您像我一样以前没有见过 e2fsck 中的这个新功能,那么这里有一些可能有用的详细信息。

e2fsck 的“scratch_files”配置选项在版本 1.40.x 期间的某个时候可用。(在我们的例子中,我们必须升级到最新的 Debian 发行版才能获得此功能。)

除了建议的“directory = /var/cache/e2fsk”选项外,还有一些进一步的配置选项可以微调临时文件存储的使用方式。我使用了“dirinfo = false”,因为文件系统有大量文件,但没有那么多目录。如果情况相反,“icount”选项将是合适的。这些选项都记录在 e2fsck.conf 的手册页中。

顺便说一句,Ted T'so 在此主题

我发现 e2fsck 运行速度极慢,比 Ted 预测的要慢得多。它大部分时间的 CPU 利用率都高达 99.9%(在一台速度极慢的旧处理器上),这表明将这些数据结构存储在磁盘而不是内存上并不是导致速度变慢的主要原因。可能是文件系统中存储的其他内容导致 e2fsck 特别慢。最后,我暂时放弃了文件系统检查;文件系统应该检查,但没有错误(据我所知),所以我打算安排在更方便的时候检查它,那时我们可以承受长达一周的停机时间。

答案3

如果您的文件系统非常大,最好尝试迁移到 64 位内核。在某些情况下,e2fsck即使使用临时文件,32 位也会耗尽内存(有关如何使用它们,请参阅 @womble 的回答或man e2fsck)。

我有一个这样的设置,使用 11 TiB 文件系统作为备份目标 - 带有大量硬链接 - 我最近将其升级到 64 位,只是为了能够在e2fsck没有从外部媒体启动的情况下运行。有问题的机器是一个非常旧的盒子,只有 2 GiB 的 RAM,但它有一个 64 位 CPU。操作系统是 32 位的,因为它已经升级了十多年,但在将备份 FS 扩大到超过(我认为)5 TiB 后,我不再能够在其上运行 e2fsck,尽管有 5 GiB 交换并配置e2fsck为使用临时文件。

但是,在 64 位升级后,它现在似乎能够完成;至少在运行了大约 18 个小时后,它目前已完成近 80%;以前它从未能够接近这个状态。我猜测它在 32 位系统上总是失败的原因在于临时文件本身的大小;目前其中一个文件的大小超过 3.3 GiB。

当然,如果CPU不支持64位,情况就比较困难,但是几乎所有支持足够大物理磁盘的系统都可能会遇到这个问题。

编辑:该过程的内存使用情况的一个例子e2fsck

VmPeak: 10687568 kB
VmSize: 10687568 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:   1706284 kB
VmRSS:    715104 kB
RssAnon:      417312 kB
RssFile:      297792 kB
RssShmem:          0 kB
VmData:  3151052 kB
VmStk:       132 kB
VmExe:       232 kB
VmLib:      1888 kB
VmPTE:      8676 kB
VmSwap:  1550760 kB

如图所示,该进程拥有高达 10 GiB 的地址空间,尽管实际VmData大小仍在启用 PAE 的系统的 4 GiB 限制之内,因此在 32 位机器上它根本无法成功完成当然,从技术上来说,32 位版本可能以不同的方式处理地址空间,但我不会依赖它。

相关内容