我有一个运行java应用程序的tomcat,偶尔会累积套接字句柄,并达到我们为最大打开文件(100K)configuration(包括软和硬)的ulimit。 发生这种情况时,Java似乎仍然活着,但我们不能再访问它。
然而,我的问题是关于这种情况伴随着一个奇怪的现象: 我不能在tomcat文件夹内mkdir 。
[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来解决。 任何关于如何解决这个问题的build议,并能重新启动mkdir吗?
安装程序是在AWS下运行的CentOS 6.5,从EBS卷安装上述的tomcat磁盘。
运行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 find /proc | wc -l返回62497876 (62M),这可能会达到一些操作系统限制; 在一个类似的健康系统,它更像1800000(1.8M)。
巨大的占用子文件夹似乎是/proc/<my-java-pid>/task (〜62M项目相比,在健康的系统上约1.7M)。 这可能只是我的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
我会很高兴分享/提供任何其他build议的发现。
我希望能够秘密地理解这种奇怪的行为,可以揭示造成这一切混乱的病态。 但是,这只是我的私人希望:)
在大多数情况下(显然不是你的情况),原因将是你用尽了iNodes。
要检查这个运行df -i:
Filesystem Inodes IUsed IFree IUse% Mounted on [...] 25600 25600 0 100% /foo
在这里你可以看到iNodes的使用率是100%。
我find了“如何解决这个情况”这个问题的答案。 我不知道所有的细节如何,但我知道足够的答案。
简短的回答:卸载磁盘,在其上运行chkdsk -f ,并重新安装回来解决并防止问题重现。 作为替代,创build一个新的磁盘(记住我们在AWS上)并将所有数据复制到新磁盘( rsync -a是我的select命令),并用它来replace原始磁盘也可以解决和防止。
较长的回答:当创build磁盘快照时,磁盘文件系统(ext4)似乎已经达到某种不稳定状态。 后来200GB的原始快照已经被扩展(使用resize2fs )到1TB,似乎从某种意义上说它在内部一直记住200GB的原始大小,造成各种怪异的现象,最终导致操作系统无法closures句柄,从而使Tomcat达到其文件限制,从而彻底解散。
最长的答案,更多的侦探工作细节:当我们有这种病理发生的突破发生在两个单独的设置并行。 检查出这些设置和比较的所有参数,我们意识到驱动器上的df -h显示了这个结果:
/dev/xvdc 1008G 197G 760G 19% /mnt/eternal
现在这个还没有引起我们的注意,因为磁盘还剩下足够的空间。 但这两个设置上的磁盘使用量(197G)完全相同,没有理由发生。 从这里迅速展开。 如前所述,我们的AWS实例是通过磁盘快照为200GB的映像创build的,该映像在使用resize2fs单个实例上进行了扩展 – 通常最大为1TB。 我们终于可以通过启动一个新的实例重新创build一个“坏的状态”,调整到1TB,并创build一个300GB的大文件。 这样做的时候,系统没有冻结,但是它确实performance出了同样的奇怪行为:
/dev/xvdc 1008G 197G 760G 19% /mnt/eternal
而且当磁盘上有超过197GB的数据。 所以,我们在两个单独的干净的设置上尝试了上面提到的两个方法(chkdsk和重新创build磁盘),并且每个这些怪异的行为都不会出现。
我们最好的猜测是,在AMI创build的某个时候,快照过程中出现了一些问题 – 很可能是因为我们采取了“无需重新启动的快照”(虽然我们通常不会,而且我也没有证据可以certificate)这个,所以我希望我们的DevOps不要因为无理责备她而生气)。 总而言之,一个有趣的经验。