Apache Tomcat 达到最大文件限制后,mkdir:特定文件夹上出现“设备上没有剩余空间”

Apache Tomcat 达到最大文件限制后,mkdir:特定文件夹上出现“设备上没有剩余空间”

问题:

我有一个运行 Java 应用程序的 Tomcat,它偶尔会累积套接字句柄并达到我们为 max-open-files 配置的 ulimit(软和硬),即 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无需重启即可再次运行?


我收集的一些指针和线索:

该设置是在 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返回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

我很乐意分享/提供任何其他建议的发现。

我暗自希望了解这种怪异行为能揭示导致整个混乱的病因。但这只是我个人的希望 :)

答案1

在大多数情况下(显然不是您的情况),原因是您用完了 iNode。

要检查此运行 df -i:

Filesystem            Inodes   IUsed   IFree IUse% Mounted on
[...]
                       25600   25600       0  100% /foo

这里您可以看到 iNode 的使用率为 100%。

坏消息是,根据https://superuser.com/questions/585641/changing-max-inode-count-number-in-ext3-filesystem-in-cent-os您需要使用 -i 选项重新创建文件系统,以增加 inode 的数量。

答案2

我找到了“如何解决这种情况”这个问题的答案。我不知道这件事发生的所有细节,但我知道的足以给出答案。

简短回答:卸载磁盘,chkdsk -f在其上运行,然后重新安装可以解决并防止问题再次发生。作为替代方案,创建一个新磁盘(记住我们在 AWS 上)并将所有数据复制到新磁盘(这rsync -a是我选择的命令)并使用它来替换原始磁盘也可以解决和防止问题。


较长的答案:磁盘文件系统 (ext4) 在最初创建磁盘快照时似乎已达到某种不稳定状态。当后来将 200GB 的原始快照扩展(使用resize2fs)到 1TB 时,似乎在某种意义上它一直在内部记住 200GB 的原始大小,从而产生各种奇怪的现象,最终导致操作系统无法关闭句柄,从而使 Tomcat 达到其文件限制,从而导致一切都崩溃。


这是最长的答案,包含更多侦查工作细节:当我们在两个不同的设置上同时发生这种病症时,我们取得了突破。检查这些设置上的所有参数并进行比较后,我们意识到df -h驱动器上显示的是以下结果:

/dev/xvdc            1008G  197G  760G  19% /mnt/eternal

现在,这之前并没有引起我们的注意,因为磁盘仍然有足够的空间。但两个设置上的磁盘使用量完全相同(197G),这没有理由发生。从这里开始,事情很快就展开了。如前所述,我们的 AWS 实例是从具有 200GB 磁盘快照的映像创建的,该映像在单个实例上使用时会扩展resize2fs- 通常最大大小为 1TB。我们最终能够通过启动新实例、调整为 1TB 并创建一个 300GB 的大文件来重新创建“坏状态”。完成后,系统没有冻结,但确实表现出相同的奇怪行为:

/dev/xvdc            1008G  197G  760G  19% /mnt/eternal

并且磁盘上的数据显然超过 197GB。因此,我们在两个单独的干净设置上尝试了上述两种方法(chkdsk 和重新创建磁盘),在每个设置上都不再出现奇怪的行为。

我们最好的猜测是,在创建 AMI 的某个时刻,快照过程中出现了问题 - 最有可能是因为我们拍摄了“未重启快照”(虽然我们通常不会这样做,而且我也没有证据支持这一点,所以我希望我们的 DevOps 不会因为我无缘无故地责怪她而生我的气!)。总而言之,这是一次有趣的经历。

相关内容