如何确定哪些进程的大部分inode已打开

这是我的问题,在慕尼黑图表visibile:

慕尼黑inode图表

我使用/打开的inode“突然”不断增加。

有没有办法确定哪个进程保持当前打开的inode最多? 我用https://unix.stackexchange.com/questions/117093/find-where-inodes-are-being-使用的方法,并find并清理一些文件夹与邮件和日志,我可以摆脱…仍然,如果inode是开放的,那么必须有一些进程保持使用,对吧? 这可能不一定是增加来自文件最多的文件夹 – 或者我错了吗?

所以我想看看是谁让他们打开,然后跟踪使用情况,看看增加的来源

更新

基于Andrew的脚本,我创build了一个也显示进程名称的版本。 因为我有一些运行的nginx / apache进程可能会重新生成,所以我希望在进程名称上看到结果。

for dir in /proc/*/fd; do echo -n "$dir "; pid=`expr "$dir" : '\/proc\/\(.*\)\/.*'`; # extract the pid pname=`ps -p $pid -o comm=`; # grab process name echo -n "$pname "; ls $dir 2>/dev/null | wc -l; done | sort -n -k 3 

示例输出:

 /proc/4612/fd sshd 49 /proc/46470/fd node 60 /proc/5655/fd nginx 66 /proc/6656/fd nginx 76 /proc/7654/fd nginx 81 /proc/8578/fd dovecot 107 /proc/9657/fd nginx 117 /proc/3495/fd java 146 /proc/4785/fd mysqld 382 

因此,下一个testing将logging随时间推移的分布情况,以了解哪些变化以及它与Morgan提到的/ proc / sys / fs / inode-nr数量之间的关系

一年之后…

一段时间过去了,这是一个新的图表 munin打开inode

并猜测9月底是错误的驱动器被replace的地方。 所以看起来整个混乱是由磁盘错误产生的。 尽pipe如此,脚本仍然是有用的!

计算每个/proc/[PID]/fd目录中的条目数。 这会给你每个进程打开的文件描述符的数量。 尽pipe枚举所有进程需要一些时间,但在进行计数时启动或停止的进程不会成为问题,因为您正在寻找一个具有大量打开文件描述符的长期进程。

像这样的东西:

for dir in /proc/*/fd; do echo -n "$dir "; #need a space to get real columns for the sort ls $dir 2>/dev/null | wc -l; done | sort -n -k 2

输出的最后一行将显示/ proc / [PID] / fd目录,并为每个进程打开文件描述符。 罪魁祸首应该靠近底部。

请注意,/ proc / [PID] / fd中的每个条目在技术上都是一个文件描述符,而不是一个独立的open inode,每个独立的open inode必须在/ proc / [PID] / fd目录中至less有一个单独的文件描述符。

我认为这里的问题部分是由于“开放的inode”而导致的。 我默认安装的munin有两个插件来获取分配的inode的数量:

“/ etc / munin / plugins / open_inodes”,它从“/ proc / sys / fs / inode-nr”

“/ etc / munin / plugins / df_inode”,它从“df -i”的输出获取度量。

这些数字是现有文件的反映,而不是系统上所有进程使用的文件/ inode的数量。

例如,这个脚本创build了10个文件,在它终止之后,我们可以在“df -i”和inode-nr中看到inode分配的增加。

  #!/usr/bin/python f0 = open("foo0", "w") f1 = open("foo1", "w") f2 = open("foo2", "w") f3 = open("foo3", "w") f4 = open("foo4", "w") f5 = open("foo5", "w") f6 = open("foo6", "w") f7 = open("foo7", "w") f8 = open("foo8", "w") f9 = open("foo9", "w") 

但是,如果我调整这一点,以防止程序终止(和文件已经存在)…文件被留下“打开”和“使用中”的过程。

  #!/usr/bin/python import time f0 = open("foo0", "w") f1 = open("foo1", "w") f2 = open("foo2", "w") f3 = open("foo3", "w") f4 = open("foo4", "w") f5 = open("foo5", "w") f6 = open("foo6", "w") f7 = open("foo7", "w") f8 = open("foo8", "w") f9 = open("foo9", "w") time.sleep(600) 

我们可以看到反映在“lsof -p PID”的输出中

 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ... open_some 6602 morgan 3w REG 254,1 0 262198 /home/morgan/src/foo0 open_some 6602 morgan 4w REG 254,1 0 262273 /home/morgan/src/foo1 open_some 6602 morgan 5w REG 254,1 0 262284 /home/morgan/src/foo2 open_some 6602 morgan 6w REG 254,1 0 262287 /home/morgan/src/foo3 open_some 6602 morgan 7w REG 254,1 0 262289 /home/morgan/src/foo4 open_some 6602 morgan 8w REG 254,1 0 262301 /home/morgan/src/foo5 open_some 6602 morgan 9w REG 254,1 0 262302 /home/morgan/src/foo6 open_some 6602 morgan 10w REG 254,1 0 262309 /home/morgan/src/foo7 open_some 6602 morgan 11w REG 254,1 0 262457 /home/morgan/src/foo8 open_some 6602 morgan 12w REG 254,1 0 268672 /home/morgan/src/foo9 

但是我可以根据需要多次运行这个“打开并保持打开”脚本,并且不会更改df / inode-nr中的数字。

所以,简而言之,munin正在报告分配的inode的数量,而不是所有进程使用的所有inode的数量。 如果在删除了一堆文件之后,munin图不能反映free'd inode,那么可能只是图表没有被重新生成,或者在所示的例子中,图表的时间尺度太长而无法反映突变。

如果这是因为日志文件,这些inode在清理之后就不会被释放。 尝试重新启动打开了这些日志文件的服务,或者在备份要从日志中保存的任何数据之后,您可以真正清除日志文件,而无需重新启动echo "" > logfilenamegoeshere日志文件名称。

从作者的博客文章中find一个“文件访问跟踪”实用程序“fatrace”,可以在这里下载。 它将显示访问系统上任何文件的所有进程。