低内存机器上的e2fsck:我可以从scratch_files或交换中获得更多吗?

我在一台32位机器上运行CentOS 6,内存为1 GB。

我有一个1TB的外部硬盘,我试图运行e2fsck。 它运行了大约一个半小时,然后Error storing directory block information (inode=45206324, block=0, num=39291127): Memory allocation failed 。 find这个问题后 ,我用指定的内容创build了/etc/e2fsck.conf ,根据这个问题的答案,创build了一个20GB的交换文件(我只有一个磁盘,所以不能将多个磁盘拆分到多个磁盘上)。 已经有2GB的交换空间。

在发生故障时,在scratch_files目录中使用了大约325MB,交换使用率为550MB。 新的20GB交换文件没有被触及。 在e2fsck: aborted程序死亡之前,CPU占用了大约2%的CPU使用时间:45分钟e2fsck: aborted ,交换恢复到大约65 MB。

使用iostat -dx ,我发现主磁盘的利用率是4.3%,而外部驱动器是7.2%,而e2fsck仍在运行(但失败),但是当CPU处于100%时我没有这样做,所以我不不知道是什么样的。 程序终于中止后,这些磁盘利用率没有变化。

所以我的问题是:为什么没有使用交换空间或用临时文件填满磁盘e2fsck失败? 还有什么我可以尝试修复这个磁盘使用这台机器? 这是3000英里远…

编辑:这里是内存故障之前top的内存相关行:

 Mem: 1029080k total, 1010780k used, 18300k free, 309780k buffers Swap: 23019504k total, 71796k used, 22947708k free, 433072k cached 

之后,仍然在运行:

 Mem: 1004.961M total, 991.344M used, 13.617M free, 1728.000k buffers Swap: 21.953G total, 541.621M used, 21.424G free, 27.949M cached 

编辑2

我用strace再次运行了e2fsck 。 有趣的是,它能够运行更长时间,CPU使用时间大约为220分钟,使用率大约为70%( stracetail占用了另外的30%)。 该程序使其达到1832 MB的虚拟内存,811 MB的常驻内存和105 MB的共享内存。 这里是从失败的内存分配strace线:

 22648 mremap(0x32ebc000, 1675546624, 2513317888, MREMAP_MAYMOVE) = -1 ENOMEM (Cannot allocate memory) 22648 mmap2(NULL, 2513317888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) 22648 mmap2(NULL, 2513453056, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) 22648 mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb2ca5000 22648 munmap(0xb2ca5000, 372736) = 0 22648 munmap(0xb2e00000, 675840) = 0 22648 mprotect(0xb2d00000, 135168, PROT_READ|PROT_WRITE) = 0 22648 mmap2(NULL, 2513317888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) 

阅读和写作似乎没有什么奇怪的事情发生:

 22648 _llseek(3, 755934822400, [755934822400], SEEK_SET) = 0 22648 write(3, "/\276\0\0|}\33xA\236\0d/\243\0\0A\236\0\\\0\0\0\0\177\303\363x8\200\0\4"..., 4096) = 4096 22648 lseek(3, 260845568, SEEK_SET) = 260845568 22648 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096 22648 _llseek(3, 755934793728, [755934793728], SEEK_SET) = 0 22648 write(3, "\376\355\372\317\1\0\0\22\0\0\0\0\0\0\0\6\0\0\0\23\0\0\0\0\0\21\0\205\0\0\0\0"..., 4096) = 4096 22648 write(1, "I", 1) = 1 22648 write(1, "node", 4) = 4 22648 write(1, " ", 1) = 1 22648 write(1, "46217250", 8) = 8 22648 write(1, " is too big. ", 14) = 14 22648 write(1, "Truncate? yes\n\n", 15) = 15 

我不是e2fsck专家。 我假设e2fsck确实在乎它看到的内存是真实的RAM还是交换。 页面可以locking到内存中。 我假设有多less内存被locking的信息可以通过/ proc或ps,top,…你可以监视这个值。

显然,唯一好的解决scheme是将磁盘连接到更好的硬件。 对你很困难。 但它甚至可能有助于不通过networking进行物理连接。 如果有另一个Linux系统与您的LAN连接并且有更多的RAM,则可以将设备导出为networking块设备。 大概还比我的下一个想法更快。

如果问题是e2fsck需要“真正的”内存,那么你可以用一个小小的Linux安装创build一个虚拟机(没有什么比e2fsck更需要的了)。 这个虚拟机可以configuration2,4,16 GiB的“RAM”。 要检查的设备可以作为块设备导出(在VM中显示为磁盘)。 无论如何,使用scratch_filesfunction可能是有意义的。 这显然是一场表演噩梦,但我想你已经接受了这个类别的任何可能的解决scheme。

编辑1

您可以通过以下方式查看进程locking到RAM中的虚拟内存量:

 grep VmLck /proc/$PID/status 

编辑2

这里是从dmesg相关的设备sdb的一切。 EXT4-fs的错误是我首先运行e2fsck的原因。

 sd 0:0:0:0: [sdb] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB) sd 0:0:0:0: [sdb] Write Protect is off sd 0:0:0:0: [sdb] Mode Sense: 28 00 00 00 sd 0:0:0:0: [sdb] Assuming drive cache: write through sd 0:0:0:0: [sdb] Assuming drive cache: write through sdb: sdb1 sd 0:0:0:0: [sdb] Assuming drive cache: write through sd 0:0:0:0: [sdb] Attached SCSI disk EXT4-fs (sdb1): barriers disabled EXT4-fs (sdb1): warning: mounting fs with errors, running e2fsck is recommended EXT4-fs (sdb1): recovery complete EXT4-fs (sdb1): mounted filesystem with ordered data mode. Opts: SELinux: initialized (dev sdb1, type ext4), uses xattr EXT4-fs error (device sdb1): ext4_lookup: deleted inode referenced: 46006273 EXT4-fs (sdb1): ext4_check_descriptors: Checksum for group 0 failed (2332!=0) EXT4-fs (sdb1): group descriptors corrupted! EXT4-fs (sdb1): ext4_check_descriptors: Checksum for group 0 failed (34754!=0) EXT4-fs (sdb1): group descriptors corrupted! EXT4-fs (sdb1): ext4_check_descriptors: Checksum for group 0 failed (34754!=0) EXT4-fs (sdb1): group descriptors corrupted!