web-dev-qa-db-ja.com

30日以上経過したファイルを適切に削除する

15000ファイル以上のキャッシュフォルダがあります。

私はこれを試しました:

find cache* -mtime +30 -exec rm {} \;

しかし、これは私のサーバーの負荷を空に飛ばしました!

より速い/より良い解決策はありますか?

または、このコマンドの速度または反復を制限するできますか?

8
Kristian

私はこれらのことに tmpwatch を使用するのが好きです。これは、ファイルが最後に変更されたときです。それは単純で、多くの場合うまく機能します:

tmpwatch -m 720 /path/to/cache

Ubuntuの場合は、代わりに tmpreaper を確認してください。

ファイルが最後にアクセスされた時刻を確認する場合は、以下を使用します。

tmpwatch -a 720 /path/to/cache

Noatimeでマウントされたファイルシステムでtmpwatch-aを使用することはできません。引き続き-mを使用できます

9
WojonsTech

を使用すると、ファイルごとに新しいプロセスが生成されるのを回避できます。

find cache* -mtime +30 -delete
6
chiborg

ニースで上記を実行してみてください:

Nice -n 39 find cache* -mtime +30 -exec rm -f {} ';'

そうすれば、他に何も実行する必要がない場合にのみ巨大な負荷が発生します。そうでない場合は、他のプロセスが優先されます(それらの良さが19未満、つまり最大の場合)。

-nオプションの引数は、-20から19の間で変化するデフォルトのnicenessに追加されることに注意してください。元のnicenessに関係なく、very niceになるように39を使用しました。

3

Chiborgがコメントしているように、この負荷は、見つかったすべてのファイルに対してrmを開始することによるものです。代わりにtmpwatchが提案されているという答えに気づきましたが、これは確実にうまく機能します。ただし、必須ではありません。

Findは、次のように、見つかったファイルを引数のリストに累積するように指示した場合、execに指定されたコマンドを1回実行できます。

find /path -name "*.moo" -exec rm {} \+

引数リストがシェルで許可されている最大値(getconf ARG_MAX)よりも大きくなる(バイト単位)ため、これが機能しない場合があります。これは、-Lオプションを指定したxargsで解決できます。

この例を考えてみましょう。

$ echo 0 > /tmp/it; 
$ for i in {0..15000};do echo $i;done  |\
    xargs --no-run-if-empty -L 5000 ./tmp/xr.sh 
Iteration=0; running with 5000 arguments
Iteration=1; running with 5000 arguments
Iteration=2; running with 5000 arguments
Iteration=3; running with 1 arguments

$ cat tmp/xr.sh 
#!/bin/sh
IT=`cat /tmp/it`
echo Iteration=$IT\; running with $# arguments
let IT=IT+1
echo $IT > /tmp/it

したがって、追加のソフトウェアをインストールする必要はありません。必要なのはgnu-findutilsだけです。

find /path -mtime +30 -print0 | xargs -0 -L 5000 rm