削除されたがまだアプリケーションで開いている大きなファイルをどのように見つけますか?プロセスが開いていても、そのようなファイルを削除するにはどうすればよいですか?
状況は、ログファイルを非常に多くの量でいっぱいにするプロセスを実行している場合です。理由はわかっています。修正できます。それまでは、プロセスをシャットダウンせずにログファイルをrmまたは空にしたいと思います。
単にrm output.log
はファイルへの参照のみを削除しますが、プロセスが終了するまでディスク上のスペースを占有し続けます。さらに悪いことに、rm
ingの後で、ファイルの場所や大きさを見つける方法がなくなりました。別のプロセスでまだ開いている場合でも、ファイルを検索して空にする方法はありますか?
特に、DebianやRHELなどのLinuxベースのオペレーティングシステムについて言及します。
アプリケーションを強制終了できない場合は、ログファイルを削除する代わりに切り捨ててスペースを解放できます。ファイルが追加モードで開かれていない場合(_O_APPEND
_を使用)、ファイルは次にアプリケーションがファイルに書き込むときと同じ大きさで表示されます(ただし、先頭部分はスパースであり、NULバイトが含まれているように見えます) )、ただしスペースは再利用されます(ただし、Apple OS/Xはスパースファイルをサポートしていません)のHFS +ファイルシステムには適用されません)。
それを切り捨てるには:
_: > /path/to/the/file.log
_
Linuxですでに削除されている場合でも、次のようにして切り捨てることができます。
_: > "/proc/$pid/fd/$fd"
_
ここで、_$pid
_は、ファイルが開かれているプロセスのプロセスIDであり、_$fd
_は、そのファイルが開かれている1つのファイル記述子です(_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)
_
別の方法として、アプリケーションが動的にリンクされている場合は、デバッガーをアプリケーションに接続して、close(fd)
を呼び出し、その後に新しいopen("the-file", ....)
を呼び出します。
こちらのクイックスタートをご覧ください: lsof
Quickstart
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)
Red Hatシステムでは、クイックスタートファイルのローカルコピーを見つけるために、通常これを行います。
[root@enterprise ~]# locate -i quickstart |grep lsof
/usr/share/doc/lsof-4.78/00QUICKSTART
...またはこれ:
[root@enterprise ~]# rpm -qd lsof
/usr/share/doc/lsof-4.78/00.README.FIRST
/usr/share/doc/lsof-4.78/00CREDITS
/usr/share/doc/lsof-4.78/00DCACHE
/usr/share/doc/lsof-4.78/00DIALECTS
/usr/share/doc/lsof-4.78/00DIST
/usr/share/doc/lsof-4.78/00FAQ
/usr/share/doc/lsof-4.78/00LSOF-L
/usr/share/doc/lsof-4.78/00MANIFEST
/usr/share/doc/lsof-4.78/00PORTING
/usr/share/doc/lsof-4.78/00QUICKSTART
/usr/share/doc/lsof-4.78/00README
/usr/share/doc/lsof-4.78/00TEST
/usr/share/doc/lsof-4.78/00XCONFIG
/usr/share/man/man8/lsof.8.gz
実際にはfree割り当てられたスペースはファイルシステムドライバーの責任です。これは通常、一度だけ発生しますallそのファイルを参照するファイル記述子が解放されます。したがって、アプリケーションでファイルを閉じない限り、実際にスペースを再利用することはできません。つまり、それを終了するか、デバッガで「少し」操作します(たとえば、ファイルを閉じて、再度開かれたり書き込まれたりしないようにするか、/dev/null
代わりに)。または、カーネルをハックすることもできますが、それはお勧めしません。
Stephaneが示唆するようにファイルを切り捨てることは役立つかもしれませんが、実際の結果はファイルシステムにも依存します(たとえば、事前に割り当てられたブロックは、いずれにせよファイルを閉じた後にのみ解放される可能性があります)。
この動作の背後にある理論的根拠は、カーネルがそのようなファイルをターゲットとするデータ要求(読み取りと書き込みの両方ですが、読み取りは実際にはより重要です)をどう処理するかを知らないということです。