開いているが削除された大容量ファイルの検索と削除

開いているが削除された大容量ファイルの検索と削除

削除されたがまだアプリケーションで開いている大容量ファイルを見つける方法は?プロセスにそのファイルが開いていても、どのように削除できますか?

状況は、私たちが驚くべき速度でログファイルを埋めるプロセスを実行しているということです。原因を知って修復できます。それまでは、プロセスを閉じずにログファイルをrmまたは消去したいと思います。

単に実行すると、rm output.logファイルへの参照のみが削除されますが、プロセスが終了するまでディスク領域を占有し続けます。もっと悪いのは、ingの後にrmファイルがどこにあるのか、どのくらい大きいのかわからないということです!ファイルが別のプロセスでまだ開いていても、ファイルを見つけて空にする方法はありますか?

特に、DebianやRHELなどのLinuxベースのオペレーティングシステムに言及しています。

答え1

アプリケーションを終了できない場合は、スペースを解放するために削除するのではなく、ログファイルを切り捨てることができます。ファイルが追加モードで開かれていない場合(使用はO_APPENDリサイクルされます(ただし、スパースファイルをサポートしていないApple OS / XのHFS +ファイルシステムには適用されません)。

切り取り:

: > /path/to/the/file.log

削除された場合、Linuxは次の操作を実行して切り捨てることができます。

: > "/proc/$pid/fd/$fd"

$pidファイルを開いたプロセスのプロセスIDと$fdそのファイルが開かれたファイル記述子(lsof -p "$pid"

pidがわからず、削除されたファイルを探している場合は、次のことができます。

lsof -nP | grep '(deleted)'

lsof -nP +L1@user75021が言ったようにより良い(より安定した、より移植性の高い)オプション(リンクが1つ未満のファイルのリストを表示)。

または(Linuxの場合):

find /proc/*/fd -ls | grep  '(deleted)'

または、次のコマンドを使用して大きなものを見つけますzsh

ls -ld /proc/*/fd/*(-.LM+1l0)

アプリケーションが動的にリンクされている場合のもう1つの方法は、デバッガを接続して呼び出すようにしてから、close(fd)新しいデバッガを呼び出すことですopen("the-file", ....)

答え2

ここでクイックスタートを確認してください。lsofクイックスタート

lsofクイックスタートファイル(lsofに含まれています)に言及した人が誰もいないことに驚きました。セクション「3.a」は、開いていてリンクされていないファイルを見つける方法を示しています。

lsof -a +L1 *mountpoint*

たとえば、

[root@enterprise ~]# lsof -a +L1 /tmp
COMMAND   PID   USER   FD   TYPE DEVICE    SIZE NLINK  NODE NAME
httpd    2357 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
mysqld   2588  mysql    4u   REG 253,17      52     0  1495 /tmp/ibY0cXCd (deleted)
mysqld   2588  mysql    5u   REG 253,17    1048     0  1496 /tmp/ibOrELhG (deleted)
mysqld   2588  mysql    6u   REG 253,17       0     0  1497 /tmp/ibmDFAW8 (deleted)
mysqld   2588  mysql    7u   REG 253,17       0     0 11387 /tmp/ib2CSACB (deleted)
mysqld   2588  mysql   11u   REG 253,17       0     0 11388 /tmp/ibQpoZ94 (deleted)
httpd    3457   root   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8437 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8438 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8439 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8440 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8441 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8442 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8443 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd    8444 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd   16990 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd   19595 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd   27495 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd   28142 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)
httpd   31478 apache   29u   REG 253,17 3926560     0  1499 /tmp/.NSPR-AFM-3457-9820130.0 (deleted)

答え3

実際にはファイルシステムドライバによって異なります。無料割り当てられたスペースは通常一度だけ発生します。みんなファイルを参照するファイル記述子が解放されます。したがって、アプリケーションがファイルを閉じることを許可しないと、実際にスペースを取り戻すことはできません。これは、ファイルを終了するか、デバッガで「少し」使用することを意味します(たとえば、ファイルを閉じて再度開いたり書き込んだりしないようにするか、代わりに/dev/nullファイルを開くなど)。またはカーネルをハッキングすることもできますが、そうしないことをお勧めします。

Stephaneが提案したようにファイルを切り捨てると役立ちますが、実際の結果はファイルシステムによって異なります(たとえば、事前に割り当てられたブロックはファイルを閉じた後にのみ解放できます)。

この動作の根拠は、カーネルがそのファイルに対するデータ要求(読み取りと書き込み、実際には読み取りがより重要である)を処理する方法がわからないためです。

答え4

現在終了できないプロセスによって保存されているファイルを削除する代わりに、次のコマンドを使用してログファイルを消去できますecho

echo -n > /var/log/myapp.log

その後、コマンドを使用して確認できますdf。 「使用されたバイト」列は減らす

関連情報