我最近在开发Web服务器上安装了Munin,以跟踪系统使用情况。 我曾经说过,即使磁盘使用率几乎没有增加,系统的inode使用率也在以每天7-8%左右的速度攀升。 我猜测有些东西正在写很多小文件,但我找不到什么/在哪里。
我知道如何find磁盘空间的使用情况,但似乎无法find总结inode使用情况的方法。
有没有一种好的方法来确定目录的inode使用情况,以便我可以find使用的来源?
不要期望这个快速运行…
cd到您怀疑可能有一个包含大量inode的子目录的目录。 如果这个脚本需要大量的时间,你可能会发现文件系统中的哪个地方。 / var是一个好的开始…
否则,如果您更改到该文件系统中的顶层目录并运行此操作并等待它完成,则会find包含所有inode的目录。
find . -type d | while read line do echo "$( find "$line" -maxdepth 1 | wc -l) $line" done | sort -rn | less
我不担心分拣的成本。 我跑了一个testing,sorting通过未经sorting的输出,对350,000目录花了8秒钟。 最初的发现。 真正的成本是在while循环中打开所有这些目录。 (循环本身需要22秒)。 (testing数据在一个有35万个目录的子目录上运行,其中一个有100万个文件,其余的有1到15个目录)。
不同的人指出,因为它把输出分类,所以ls不是很大。 我曾尝试回声,但这也不是很好。 有人指出,统计给出了这个信息(目录条目的数量),但它不是可移植的。 事实certificate,find -maxdepth在打开目录和统计.files文件时真的很快,所以…在这里,它是每个人的点数!
Grrr,评论需要50名代表。 所以这个答案实际上是对克里斯答案的评论。
由于提问者可能不关心所有的目录,只有最差的,然后使用sorting可能是非常昂贵的矫枉过正。
find . -type d | while read line do echo "$(ls "$line" | wc -l) $line" done | perl -a -ne'next unless $F[0]>=$max; print; $max=$F[0]' | less
这并不像你的版本那样完整,但是如果它们大于以前的最大值,打印线会大大减less打印出来的噪音量,并节省sorting费用。
这个缺点是如果你有两个非常大的目录,而第一个比第二个有更多的inode,你永远不会看到第二个。
更完整的解决scheme是编写一个更智能的Perl脚本,跟踪前10个值,并在最后打印出来。 但是,对于快速的服务器故障来说,这太长了。
此外,一些中等智慧的perl脚本可以让你跳过while循环 – 在大多数平台上,ls对结果进行sorting,而且对于大型目录也是非常昂贵的。 因为我们所关心的只是计数,所以在这里并不是必要的。
如果问题是一个文件太多的目录,这是一个简单的解决scheme:
# Let's find which partition is out of inodes: $ df -hi Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda3 2.4M 2.4M 0 100% / ... # Okay, now we know the mount point with no free inodes, # let's find a directory with too many files: $ find / -xdev -size +100k -type d
find线后面的想法是,目录的大小与直接在该目录内的文件数量成正比。 所以,我们在这里查找里面有大量文件的目录。
如果你不想猜测一个数字,并且喜欢按“大小”排列所有可疑的目录,那也很简单:
# Remove the "sort" command if you want incremental output find / -xdev -size +10k -type d -printf '%s %p\n' | sort -n
你可以使用这个小片段:
find | cut -d/ -f2 | uniq -c | sort -n
它会打印出当前文件夹中每个目录中有多less个文件和目录,底部最多的是违规者。 它会帮助你find有很多文件的目录。 ( 更多信息 )
这不是直接回答你的问题,但使用findsearch最近修改的小文件可能会缩小search范围:
find / -mmin -10 -size -20k
find /path ! -type d | sed 's,/[^/]*$,,' | uniq -c | sort -rn
ls不会find名称以句点开头的文件。 使用查找避免了这一点。 这将查找目录树中的每个文件,从每个path末尾剥离基本名称,并计算每个目录path在结果输出中出现的次数。 你可能不得不把“!” 在引号中,如果你的shell抱怨的话。
Inode也可以被已经被删除但被正在运行的进程保持打开的文件用完。 如果这个Munin包包含任何不断运行的程序,另一个要检查的是它是否持有不正常数量的文件。
我会强奸这一个:在整个设备上运行Tripwire作为基准线,然后在一段时间后再进行检查,违规目录将像拇指一样突出显示。
(不能评论真的变老了 – 这是egorgry)
egorgry – ls -i打印条目的inode NUMBER,而不打印inode COUNT。
尝试使用目录中的文件 – 您可能(可能)会看到一个相同的数字,但这不是inode的数量,它只是您的目录条目指向的inode。
一个class轮,返回给定目录的每个孩子的inode计数,最底部的条目最多。
find . -mindepth 1 -printf "%p/%i\n" \ | awk -F/ '{print $2"/"$NF}' | sort -u \ | cut -d/ -f1 | uniq -c | sort -n
#!/bin/bash # Show inode distribution for given directory dirs=$(find $1 -mindepth 1 -maxdepth 1 -type d) for dir in $dirs do inode_count=$(find $dir -printf "%i\n" 2> /dev/null | sort -u | wc -l) echo "$inode_count $dir" done
像这样运行(假设上面的脚本驻留在工作目录的可执行文件中)
./indist / | sort -n
inode的用法大概是每个文件或目录一个,对吧? 所以呢
find [path] -print | wc -l
大致计算在[path]下使用了多less个inode。
我试图写一个高效的shellpipe道,但是它变得很笨重,要么慢或者不准确,
find . -depth -printf '%h\n' | uniq -c | awk '$1>1000'
将列出叶目录(和其他一些),其中有超过1000个文件。 所以,这里有一个Perl脚本,可以在时间和内存中高效地执行它。 输出就像
«在子树中的文件»«文件,直接在目录»«目录名»
所以你可以使用普通的工具轻松地按摩和过滤它,例如像上面的sort(1)或awk(1)。
#! /usr/bin/perl -w # Written by Kjetil Torgrim Homme <[email protected]> use strict; use File::Find; my %counted; my %total; sub count { ++$counted{$File::Find::dir}; } sub exeunt { my $dir = $File::Find::dir; # Don't report leaf directories with no files return unless $counted{$dir}; my $parent = $dir; $parent =~ s!/[^/]*$!!; $total{$dir} += $counted{$dir}; $total{$parent} += $total{$dir} if $parent ne $dir; printf("%8d %8d %s\n", $total{$dir}, $counted{$dir}, $dir); delete $counted{$dir}; delete $total{$dir}; } die "Usage: $0 [DIRECTORY...]\n" if (@ARGV && $ARGV[0] =~ /^-/); push(@ARGV, ".") unless @ARGV; finddepth({ wanted => \&count, postprocess => \&exeunt}, @ARGV);
[gregm@zorak2 /]$ ls -i /home 131191 gregm
我的笔记本电脑上使用的是131191 inode。