Я запускаю 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
Мы можем сказать, что e2fsck пытается выделить 2,5 ГБ для любой таблицы, которую он пытается придумать, и даже если у вас достаточно (виртуальной) оперативной памяти, у вас нет адресного пространства для этого в 32-разрядном процессе.
Ну ты вообще, но вы запрашиваете сразу 5/6 от него, есть вероятность, что другие сопоставления / выделения занимают оставшиеся 500 МБ адресного пространства раньше, поэтому ядро не может определить непрерывное пространство размером 2,5 ГБ, чтобы удовлетворить это mmap2.
Мой совет: попробуйте запустить загрузочный 64-разрядный Linux с USB-накопителем, используйте тот же файл подкачки объемом 20 ГБ (или под рукой есть не менее 4 ГБ подкачки), вы уже знаете, что это может занять много времени.
Кстати, я загрузил исходный код e2fsprogs, чтобы определить, может ли e2fsck запрашивать реальный баран, вызывая mlock () или mlockall (), но рекурсивное использование grepping «mlock» не дает результатов, поэтому этот путь кажется маловероятным.
Я не могу комментировать сообщения (я здесь новичок), пожалуйста, оцените мой ответ, если он полезен, чтобы я мог заработать очки репутации, которые требуются serverfault, чтобы разрешить мне комментировать сообщения.
И последнее, но не менее важное: вы можете разделить все вызовы, связанные с памятью, с помощью strace -e память e2fsck ..
Я не эксперт по e2fsck. Я предполагаю, что e2fsck действительно заботится о том, является ли видимая память реальной оперативной памятью или свопингом. Страницы можно заблокировать в памяти. Я предполагаю, что информация о том, сколько памяти заблокировано, доступна через / proc или ps, top, ... Вы можете отслеживать это значение.
Очевидно, что единственное хорошее решение - подключить диск к более качественному оборудованию. Вам сложно. Но это может даже помочь не физически, а через сеть. Если есть другая система Linux с подходящим LAN-подключением к вашей и с большим объемом оперативной памяти, вы можете экспортировать устройство для проверки как сетевое блочное устройство. Наверное, все еще быстрее, чем моя следующая идея.
Если проблема в том, что для e2fsck требуется «настоящая» оперативная память, вы можете создать виртуальную машину с крошечной установкой Linux (ничего больше, чем e2fsck ...). Эта виртуальная машина может быть сконфигурирована с 2, 4, 16 ГиБ «RAM». Проверяемое устройство может быть экспортировано как блочное устройство (отображается как диск в виртуальной машине). Вероятно, в любом случае имеет смысл использовать функцию 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!