Inodeの使用場所を決定する

Inodeの使用場所を決定する

最近、システムの使用状況を追跡するために開発 Web サーバーに Munin をインストールしました。ディスク使用量はほとんど増加していないのに、システムの inode 使用量が 1 日あたり約 7 ~ 8% 増加していることに気付きました。何かが大量の小さなファイルを書き込んでいるのではないかと思いますが、それが何で、どこにあるのかわかりません。

ディスク領域の使用量を調べる方法はわかっていますが、inode の使用量の概要を調べる方法が見つからないようです。

ディレクトリごとに inode の使用状況を判断し、使用状況の原因を特定する良い方法はありますか?

答え1

これがすぐに実行されるとは思わないでください...

多数の inode を持つサブディレクトリがあると思われるディレクトリに cd します。このスクリプトに非常に時間がかかる場合は、ファイルシステム内のどこを探せばよいかがわかっている可能性があります。/var から始めるのがよいでしょう...

それ以外の場合は、そのファイルシステムのトップディレクトリに移動してこれを実行し、完了するまで待つと、すべての inode を含むディレクトリが見つかります。

find . -type d | 
while 
  read line  
do 
  echo "$( find "$line" -maxdepth 1 | wc -l) $line"  
done | 
sort -rn | less

ソートのコストについては心配していません。テストを実行したところ、350,000 個のディレクトリに対してソートされていない出力をソートするのに 8 秒かかりました。最初の find には かかりました。実際のコストは、while ループでこれらすべてのディレクトリを開くことです (ループ自体は 22 秒かかります)。(テスト データは、350,000 個のディレクトリを含むサブディレクトリで実行されました。そのうちの 1 つには 100 万個のファイルがあり、残りには 1 ~ 15 個のディレクトリがありました)。

多くの人が、ls は出力をソートするので、その点では優れていないと指摘していました。echo も試してみましたが、これも優れていませんでした。別の人は、stat はこの情報 (ディレクトリ エントリの数) を提供しますが、移植性がないことを指摘していました。find -maxdepth はディレクトリを開くのが非常に速く、.files をカウントすることがわかりました。それで、ここにあります。皆さんにポイントをあげましょう!

答え2

問題が 1 つのディレクトリにファイルが多すぎることである場合、簡単な解決策は次のとおりです。

# 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

答え3

うーん、コメントするには 50 の評価が必要です。つまり、この回答は実際には chris の回答に対するコメントです。

質問者はおそらくすべてのディレクトリではなく、最悪のディレクトリだけを気にしているので、ソートを使用することはおそらく非常にコストのかかる過剰な作業です。

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

これはあなたのバージョンほど完全ではありませんが、行が以前の最大値より大きい場合に行を印刷し、印刷されるノイズの量を大幅に削減し、並べ替えの費用を節約します。

この方法の欠点は、非常に大きなディレクトリが 2 つあり、最初のディレクトリの inode が 2 番目のディレクトリの inode より 1 つ多い場合、2 番目のディレクトリが表示されないことです。

より完全な解決策は、最も多く表示された 10 個の値を追跡し、最後にそれらを出力する、よりスマートな Perl スクリプトを作成することです。しかし、それは serverfault の簡単な回答としては長すぎます。

また、少し賢い Perl スクリプトを使用すると、while ループをスキップできます。ほとんどのプラットフォームでは、ls は結果をソートしますが、大きなディレクトリの場合はこれも非常にコストがかかります。ここではカウントだけが必要なので、ls ソートは必要ありません。

答え4

これは質問への直接的な回答ではありませんが、find を使用して最近変更されたサイズの小さいファイルを検索すると、検索範囲が絞り込まれる可能性があります。

find / -mmin -10 -size -20k

関連情報