mkdir:Apache Tomcat 達到最大文件 ulimit 後特定文件夾上的“設備上沒有剩餘空間”
問題:
我有一個執行 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,上述 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
(約 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
我很樂意分享/提供任何其他建議的發現。
暗地裡,我希望理解這種奇怪的行為能夠闡明導致這整個混亂的病理。但是,這只是我個人的希望:)
我找到了“如何解決這種情況”問題的答案。我不知道這是怎麼回事的所有細節,但我知道的足夠多,可以給出答案。
簡短的回答:解除安裝磁碟,在其上執行
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 不要因為我無緣無故地責怪她而生氣!)。總而言之,一次有趣的經歷。
在大多數情況下(顯然不是您的情況),原因是您的 iNode 用完了。
要檢查這個執行 df -i:
Filesystem Inodes IUsed IFree IUse% Mounted on [...] 25600 25600 0 100% /foo
在這裡你可以看到 iNodes 的使用率是 100%。
壞消息是,根據https://superuser.com/questions/585641/sharing-max-inode-count-number-in-ext3-filesystem-in-cent-os,您需要使用-i 選項以增加 inode 的數量。