У меня есть кот, запускающий java-приложение, которое иногда накапливает дескрипторы сокетов и достигает установленного нами ulimit (как мягкого, так и жесткого) для max-open-files, который составляет 100K. Когда это происходит, кажется, что Java все еще жива, но мы больше не можем получить к ней доступ.
Однако мой вопрос касается странного явления, которое сопровождает эту ситуацию: Я не могу mkdir
внутри папки tomcat.
[root@server /opt/apache-tomcat-7.0.52]# mkdir some_folder
mkdir: cannot create directory `some_folder': No space left on device
Фактически, я получаю ту же ошибку в нескольких разных папках, которые находятся в /opt
, но не под /opt
прямо, а не - например - под /opt/apache-tomcat-7.0.52/logs
.
Я не могу объяснить это хоть убей, и могу решить только с помощью init 6
. Любые предложения о том, как решить проблему и иметь возможность mkdir
опять без перезагрузки?
Это CentOS 6.5, работающая под AWS, с указанным диском tomcat, смонтированным из тома EBS.
Бег df -h
показывает, что диск явно не заполнен:
[root@server ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/xvda1 9.9G 3.6G 5.9G 38% /
none 121G 0 121G 0% /dev/shm
/dev/xvdc 1008G 197G 760G 19% /mnt/eternal
Содержание /etc/fstab
(которые по какой-то причине используют двойной монтаж - не знаю почему):
/dev/xvdc /mnt/eternal ext4 defaults 0 0
/mnt/eternal /opt ext4 defaults,bind 0 0
И соответствующие строки из mount
:
/dev/xvdc on /mnt/eternal type ext4 (rw)
/mnt/eternal on /opt type none (rw,bind)
Бег df -i
не намекает на что-то плохое (и похоже на здоровую систему):
[root@server ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 655360 78245 577115 12% /
none 31549847 1 31549846 1% /dev/shm
/dev/xvdc 67108864 12551 67096313 1% /mnt/eternal
Бег sysctl fs.file-nr
дает этот результат, который явно высок, но кажется далеким от предела:
[root@server ~]# sysctl fs.file-nr
fs.file-nr = 101632 0 25087252
Бег find /proc | wc -l
возвращается 62497876
(62M), что может достичь некоторого предела ОС; на аналогичной здоровой системе это больше похоже на 1800000 (1,8M).
Чрезвычайно занятая подпапка выглядит /proc/<my-java-pid>/task
(~ 62 млн элементов по сравнению с ~ 1,7 млн в исправной системе). Скорее всего, это просто отражение моих 100K fds (x2, для fds и fdinfos) более 300 отдельных папок "задач".
Это появляется в конце моего дампа dmesg (мой java pid в этом примере - 105940) - не уверен, как это может быть связано:
INFO: task java:105940 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
java D 0000000000000008 0 105940 1 0x00000080
ffff88161ab55c88 0000000000000082 ffff88161ab55c18 ffffffff8109be4f
ffffffff81ed28f0 ffff881e66360ae0 ffffffff8100bb8e ffff88161ab55c88
ffff881e66361098 ffff88161ab55fd8 000000000000fb88 ffff881e66361098
Call Trace:
[<ffffffff8109be4f>] ? hrtimer_try_to_cancel+0x3f/0xd0
[<ffffffff8100bb8e>] ? apic_timer_interrupt+0xe/0x20
[<ffffffff810521c9>] ? mutex_spin_on_owner+0x99/0xc0
[<ffffffff8151636e>] __mutex_lock_slowpath+0x13e/0x180
[<ffffffff8151620b>] mutex_lock+0x2b/0x50
[<ffffffff8111c461>] generic_file_aio_write+0x71/0x100
[<ffffffffa0121fb1>] ext4_file_write+0x61/0x1e0 [ext4]
[<ffffffff81180d7a>] do_sync_write+0xfa/0x140
[<ffffffff81096ca0>] ? autoremove_wake_function+0x0/0x40
[<ffffffff812292ab>] ? selinux_file_permission+0xfb/0x150
[<ffffffff8121bd26>] ? security_file_permission+0x16/0x20
[<ffffffff81181078>] vfs_write+0xb8/0x1a0
[<ffffffff81181971>] sys_write+0x51/0x90
[<ffffffff81517e2e>] ? do_device_not_available+0xe/0x10
[<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
Я был бы рад поделиться / предоставить любые другие предлагаемые выводы.
Втайне я надеюсь, что понимание этого странного поведения прольет свет на патологию, вызвавшую весь этот беспорядок. Но это только моя личная надежда :)
В большинстве случаев (очевидно, не в вашем случае) причина в том, что у вас заканчиваются iNodes.
Чтобы проверить это, запустите df -i:
Filesystem Inodes IUsed IFree IUse% Mounted on
[...]
25600 25600 0 100% /foo
Здесь вы можете увидеть использование iNodes на 100%.
Плохие новости, по словам https://superuser.com/questions/585641/changing-max-inode-count-number-in-ext3-filesystem-in-cent-os вам нужно воссоздать файловую систему с параметром -i, чтобы увеличить количество inodes.
Я нашел ответ на свой вопрос «как исправить этот сценарий». Я не знаю всех подробностей того, как это произошло, но я знаю достаточно, чтобы дать ответ.
Краткий ответ: размонтирование диска, запуск chkdsk -f
на нем, и установка обратно решает и предотвращает повторение проблемы. В качестве альтернативы можно создать новый диск (помните, что мы на AWS) и скопировать все данные на новый диск (rsync -a
была моей командой выбора), и использование ее для замены исходного диска также решает и предотвращает.
Более длинный ответ: файловая система диска (ext4), похоже, достигла нестабильного состояния при первоначальном создании моментального снимка диска. Когда позже исходный снимок размером 200 ГБ был расширен (с использованием resize2fs
) до 1 ТБ, похоже, что в каком-то смысле он продолжал внутренне запоминать исходный размер 200 ГБ, создавая всевозможные странные явления, в результате которых ОС не могла закрывать дескрипторы, что заставляло Tomcat достигать своего предела файла, таким образом получая весь ад вырваться.
Самый длинный ответ, с немного большим количеством деталей детективной работы: прорыв произошел, когда мы заставили эту патологию происходить параллельно в двух разных ситуациях. Проверив все параметры этих настроек и сравнив, мы поняли, что df -h
на диске показывал такой результат:
/dev/xvdc 1008G 197G 760G 19% /mnt/eternal
Раньше это не привлекало нашего внимания, потому что на диске еще достаточно места. Но это было одно и то же использование диска (197 ГБ) в обеих конфигурациях, и для этого нет причин. Отсюда дела быстро развернулись. Как упоминалось ранее, наши экземпляры AWS были созданы из образа с моментальным снимком диска размером 200 ГБ, который расширяется на отдельные экземпляры с использованием resize2fs
- обычно до максимального размера 1 ТБ. Мы наконец смогли воссоздать «плохое состояние», запустив новый экземпляр, изменив размер до 1 ТБ и создав большой файл размером 300 ГБ. Когда это было сделано, система не зависла, но показала такое же странное поведение:
/dev/xvdc 1008G 197G 760G 19% /mnt/eternal
И это когда на диске явно было больше 197 ГБ данных. Итак, мы опробовали два упомянутых выше метода (chkdsk и воссоздание диска) в двух индивидуальных настройках очистки, и в каждом из них странное поведение больше не появлялось.
Наше лучшее предположение состоит в том, что в какой-то момент при создании AMI что-то пошло не так в процессе создания моментального снимка - скорее всего, из-за того, что мы сделали «моментальный снимок без перезапуска» (хотя обычно мы этого не делаем, и у меня нет доказательств для подтверждения это вверх, так что я надеюсь, что наши DevOps не злятся на меня за то, что я обвиняю ее без причины!). В общем, интересный опыт.