で多くのファイルがあるディレクトリを見つける


33

そこで、私のクライアントは、今日、Linodeから、サーバーがLinodeのバックアップサービスを爆破させているというメールを受け取りました。どうして?ファイルが多すぎます。私は笑って走った:

# df -ih
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/xvda        2.5M  2.4M   91K   97% /

がらくた。使用中の240万iノード。一体何が起こっているのか!

明らかな容疑者(/var/{log,cache}およびすべてのサイトがホストされているディレクトリ)を探しましたが、本当に疑わしいものは見つかりません。この獣のどこかに、数百万のファイルを含むディレクトリがあると確信しています。

コンテキスト一つは私の私の忙しいサーバは、200Kのinodeと私のデスクトップ(旧中古ストレージの4TBを超えるとインストール)ばかり万人を超えているを使用しています。問題があります。

だから私の問題は、どのように問題がどこにあるのかを見つけることですか?duiノードにはありますか?



1
vmstat -1 100を実行して、その一部を示します。CS(コンテキストスイッチング)の多数に注意してください。障害のあるファイルシステムは、多くのiノードをエラーにゆだねることがあります。またはおそらく合法的に、多くのファイルがあります。このリンクは、ファイルとiノードについて通知する必要があります。stackoverflow.com/questions/653096/howto-free-inode-usage lsofコマンドを使用して、実行中または開いているものを確認する必要がある場合があります。
j0h

回答:


23

チェックイン/lost+foundの場合には、ディスク上の問題と、おそらく誤って、別々のファイルとして検出されてしまったジャンクがたくさんありました。

iostatいくつかのアプリケーションがまだ狂ったようなファイルを生成しているかどうかを確認します。

find / -xdev -type d -size +100k100kB以上のディスク容量を使用するディレクトリがあるかどうかがわかります。これは、多くのファイルを含むディレクトリ、または過去に多くのファイルを含むディレクトリになります。サイズの図を調整することもできます。

GNU duには、ディレクトリエントリごとに1をカウントするオプションの組み合わせはないと思います。これfindを行うには、awk でファイルのリストを作成し、少しカウントします。これはduiノード用です。最小限のテストで、改行を含むファイル名に対処しようとしません。

#!/bin/sh
find "$@" -xdev -depth | awk '{
    depth = $0; gsub(/[^\/]/, "", depth); depth = length(depth);
    if (depth < previous_depth) {
       # A non-empty directory: its predecessor was one of its files
       total[depth] += total[previous_depth];
       print total[previous_depth] + 1, $0;
       total[previous_depth] = 0;
    }
    ++total[depth];
    previous_depth = depth;
}
END { print total[0], "total"; }'

使用法:du-inodes /。空でないディレクトリのリストを、それらのエントリとそのサブディレクトリ内のエントリの総数とともに再帰的に出力します。出力をファイルにリダイレクトし、いつでも確認できます。sort -k1nr <root.du-inodes | head最大の犯罪者を教えてくれます。


スクリプトの所与のエラー:awk: line 2: find: regular expression compile failed (bad class -- [], [^] or [) [^ awk: line 2: syntax error at or near ] `/tmp/tmpw99dhs': Permission denied
ラドゥRădeanu

@RaduRădeanuああ、なるほど、他のバージョンでは動作しないgawkの特殊性を使用しました。POSIXに従って必要だと思うバックスラッシュを追加しました。
ジル 'SO-悪であるのをやめる'

14

このスクリプトで確認できます:

#!/bin/bash

if [ $# -ne 1 ];then
  echo "Usage: `basename $0` DIRECTORY"
  exit 1
fi

echo "Wait a moment if you want a good top of the bushy folders..."

find "$@" -type d -print0 2>/dev/null | while IFS= read -r -d '' file; do 
    echo -e `ls -A "$file" 2>/dev/null | wc -l` "files in:\t $file"
done | sort -nr | head | awk '{print NR".", "\t", $0}'

exit 0

これにより、ファイル数で上位10個のサブディレクトリが出力されます。上位xが必要な場合は、で変更headします head -n x。ここxで、0より大きい自然数です。

100%確実な結果を得るには、ルート権限でこのスクリプトを実行します。

トップブッシーフォルダー


2019:上げられました10: read: Illegal option -d... 悪いことは何も起こらないことを願って-d旗をこすり落としましたread。実行が終了したらお知らせします...
ウィリアムズ

3

検索データベースが最新の場合、多くの場合、検索よりも高速です。

# locate '' | sed 's|/[^/]*$|/|g' | sort | uniq -c | sort -n | tee filesperdirectory.txt | tail

これにより、ロケートデータベース全体がダンプされ、パスの最後の「/」以降のすべてが削除されます。次に、ソートと「uniq -c」により、ディレクトリごとのファイル/ディレクトリの数が取得されます。「sort -n」を末尾にパイプして、ほとんどのものを含む10個のディレクトリを取得します。


+1:ロケートデータベースを使用することは非常に良い考えです!
マックスベイキルヒ

何らかの理由でロケートを使用できない場合は、find /path/to/parent -xdev > filelist最初に実行してから、sedにそのリストから入力を読み取らせます。
gerrit

1

別の提案:

http://www.iasptk.com/20314-ubuntu-find-large-files-fast-from-command-line

これらの検索を使用して、サーバー上の最大のファイルを見つけます。

1GBを超えるファイルを見つける

sudo find / -type f -size + 1000000k -exec ls -lh {} \;

100MBを超えるファイルを見つける

sudo find / -type f -size + 100000k -exec ls -lh {} \;

10MBを超えるファイルを検索する

sudo find / -type f -size + 10000k -exec ls -lh {} \;

最初の部分は、「-size」フラグを使用して、キロバイト単位で測定されたさまざまなサイズのファイルを検索するfindコマンドです。

「-exec」で始まる最後の最後のビットは、見つかった各ファイルで実行するコマンドを指定できます。ここで、ディレクトリの内容を一覧表示するときに表示されるすべての情報を含める「ls -lh」コマンド。最後のhは、各ファイルのサイズを人間が読める形式で出力するため、特に役立ちます。


2
彼の問題は、大きなiノードではなく、多くの小さなファイルを指しているiノードの使用率が高いことです。
UpTheCreek

0

これは、他の人がシェルを介してAndroid上で失敗したときに私のために働いた:

find / -type d -exec sh -c "fc=\$(find '{}' -type f | wc -l); echo -e \"\$fc\t{}\"" \; | sort -nr | head -n25

0

du --inodes -d 1は、再帰的にまたは直接多くのファイルを含むディレクトリを見つけるようなものを使用するのが好きです。

私もこの答えが好きです:https : //unix.stackexchange.com/a/123052

私たちの怠け者のために、ここにその要点があります:

du --inodes -S | sort -rh | sed -n \
    '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.