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..