e2fsck на машине с небольшим объемом памяти: могу ли я получить больше от файлов scratch_files или swap?

Я использую CentOS 6 на 32-битной машине с 1 ГБ оперативной памяти.

У меня есть внешний жесткий диск емкостью 1 ТБ, на котором я пытаюсь запустить e2fsck. Он работает около полутора часов, а затем не работает с Error storing directory block information (inode=45206324, block=0, num=39291127): Memory allocation failed, Найдя этот вопрос, я создал /etc/e2fsck.conf с указанным содержанием и на основе ответов на этот вопрос создал файл подкачки объемом 20 ГБ (у меня только один диск, поэтому разделение подкачки по нескольким дискам невозможно). Уже было 2 ГБ пространства подкачки.

Во время сбоя он использовал около 325 МБ в своем каталоге scratch_files, а объем подкачки составлял 550 МБ. Новый файл подкачки на 20 ГБ не был затронут. Он завис еще на 45 минут при загрузке процессора примерно 2%, прежде чем программа умерла с e2fsck: aborted и своп вернулся примерно к 65 МБ.

С помощью iostat -dxЯ обнаружил, что загрузка основного диска составляла 4,3%, а внешнего диска - 7,2%, когда e2fsck все еще работал (но не работал), но у меня не было этого, когда процессор был на 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

Я побежал e2fsck снова используя strace, Интересно, что он мог работать гораздо дольше, занимая около 220 минут процессорного времени при использовании около 70% (strace а также tail занял остальные 30%). Программа заняла 1832 МБ виртуальной памяти, 811 МБ резидентной памяти и 105 МБ общей памяти. Вот 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

1 ответ

Я не эксперт по e2fsck. Я предполагаю, что e2fsck действительно заботится, является ли память, которую он видит, реальной ОЗУ или подкачкой. Страницы могут быть заблокированы в памяти. Я предполагаю, что информация о том, сколько памяти заблокировано, доступна через / proc или ps, top,... Вы можете отслеживать это значение.

Очевидно, что единственным хорошим решением было бы подключить диск к более качественному оборудованию. Сложно для вас. Но это может даже помочь не устанавливать это соединение физически, а через сеть. Если есть другая система Linux с подходящим для вас подключением к локальной сети и большим объемом оперативной памяти, вы можете экспортировать устройство для проверки в качестве сетевого блокирующего устройства. Вероятно, все еще быстрее, чем моя следующая идея.

Если проблема в том, что e2fsck требует "реальной" оперативной памяти, вы можете создать виртуальную машину с крошечной установкой Linux (ничего более необходимого, чем e2fsck...). Эта виртуальная машина может быть настроена с 2, 4, 16 ГиБ "ОЗУ". Проверяемое устройство может быть экспортировано как блочное устройство (отображается как диск в виртуальной машине). Вероятно, в любом случае имеет смысл использовать функцию scratch_files. Это, очевидно, было бы кошмаром производительности, но я думаю, вы уже приняли любое возможное решение в этой категории.

Редактировать 1

Вы можете увидеть объем виртуальной памяти, заблокированной процессом в ОЗУ:

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!

Мы можем сказать, что e2fsck пытается выделить 2,5 ГБ для любой таблицы, которую он пытается придумать, и даже если у вас достаточно (виртуальной) оперативной памяти, у вас нет адресного пространства для этого в 32-разрядном процессе.

Что ж, вы это делаете, но вы запрашиваете сразу 5/6 от этого, есть вероятность, что другие сопоставления / выделения занимают оставшиеся 500 МБ адресного пространства раньше, поэтому ядро ​​не может определить непрерывное пространство размером 2,5 ГБ, чтобы удовлетворить это mmap2.

Мой совет: попробуйте запустить 64-битный Linux с загрузкой через USB, используйте тот же самый файл подкачки размером 20 ГБ (или под рукой должно быть не менее 4 ГБ подкачки), вы уже знаете, что это может занять много времени.

Кстати, я загрузил исходный код e2fsprogs, чтобы определить, может ли e2fsck запрашивать реальный баран, вызывая mlock() или mlockall(), но рекурсивное использование grepping "mlock" не дает результатов, поэтому этот путь кажется маловероятным.

Я не могу комментировать сообщения (я здесь новенький), пожалуйста, оцените мой ответ, если он полезен, чтобы я мог заработать очки репутации, которые требуются serverfault, чтобы разрешить мне комментировать сообщения.

И последнее, но не менее важное: вы можете разделить все вызовы, связанные с памятью, с помощью strace -e memory e2fsck..

Другие вопросы по тегам