mkdir:Apache Tomcat 达到最大文件 ulimit 后特定文件夹上的“设备上没有剩余空间”

Yon*_*tan 6 linux tomcat centos disk-space-utilization max-file-descriptors

问题:

我有一个运行 java 应用程序的 tomcat,它偶尔会累积套接字句柄并达到我们为最大打开文件配置的 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
Run Code Online (Sandbox Code Playgroud)

事实上,我在驻留在 下的多个不同文件夹下遇到相同的错误/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
Run Code Online (Sandbox Code Playgroud)

内容/etc/fstab(出于某种原因,使用双重安装 - 不知道为什么):

/dev/xvdc       /mnt/eternal    ext4    defaults        0 0
/mnt/eternal    /opt    ext4    defaults,bind   0 0
Run Code Online (Sandbox Code Playgroud)

和适当的行mount

/dev/xvdc on /mnt/eternal type ext4 (rw)
/mnt/eternal on /opt type none (rw,bind)
Run Code Online (Sandbox Code Playgroud)

跑步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
Run Code Online (Sandbox Code Playgroud)

运行sysctl fs.file-nr给出的结果显然很高,但似乎离极限还很远:

[root@server ~]# sysctl fs.file-nr
fs.file-nr = 101632     0       25087252
Run Code Online (Sandbox Code Playgroud)

运行find /proc | wc -l返回62497876(62M),可能达到一些操作系统限制;在类似的健康系统上,它更像是 1800000 (1.8M)。

被大量占用的子文件夹似乎是/proc/<my-java-pid>/task(大约 6200 万个项目,而健康系统上大约有 170 万个项目)。这可能只是我的 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
Run Code Online (Sandbox Code Playgroud)

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

私下里,我希望理解这种奇怪的行为会阐明导致这整个混乱的病理学。但是,这只是我个人的希望 :)

Yon*_*tan 5

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

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


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


最长的答案,还有更多的侦探工作细节:突破发生在我们让这种病理在两个独立的设置中并行发生时。检查这些设置的所有参数并进行比较,我们意识到df -h驱动器上显示了以下结果:

/dev/xvdc            1008G  197G  760G  19% /mnt/eternal
Run Code Online (Sandbox Code Playgroud)

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

/dev/xvdc            1008G  197G  760G  19% /mnt/eternal
Run Code Online (Sandbox Code Playgroud)

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

我们最好的猜测是,在某个时刻,当创建 AMI 时,快照过程中出了点问题——很可能是因为我们拍摄了“没有重启的快照”(尽管我们通常不会,而且我没有证据支持)到此为止,所以我希望我们的 DevOps 不会因为我无缘无故地责备她而生我的气!)。总而言之,一次有趣的经历。


Tho*_*erk 5

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

要检查此运行 df -i:

Filesystem            Inodes   IUsed   IFree IUse% Mounted on
[...]
                       25600   25600       0  100% /foo
Run Code Online (Sandbox Code Playgroud)

在这里你可以看到 iNodes 的使用率是 100%。

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

  • 你知道inode被完全利用的原因是什么吗? (2认同)