削除されたがまだアプリケーションで開いている大容量ファイルを見つける方法は?プロセスにそのファイルが開いていても、どのように削除できますか?
状況は、私たちが驚くべき速度でログファイルを埋めるプロセスを実行しているということです。原因を知って修復できます。それまでは、プロセスを閉じずにログファイルを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
。 「使用されたバイト」列は減らす。