열려 있지만 삭제된 대용량 파일 찾기 및 삭제

열려 있지만 삭제된 대용량 파일 찾기 및 삭제

삭제되었지만 여전히 애플리케이션에 열려 있는 대용량 파일을 찾는 방법은 무엇입니까? 프로세스에 해당 파일이 열려 있어도 어떻게 삭제할 수 있나요?

상황은 우리가 놀라운 속도로 로그 파일을 채우는 프로세스를 실행하고 있다는 것입니다. 원인을 알고 고칠 수 있어요. 그때까지는 프로세스를 닫지 않고 로그 파일을 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)

애플리케이션이 동적으로 링크된 경우 또 다른 접근 방식은 디버거를 연결하여 호출하도록 한 다음 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. "사용된 바이트" 열은줄이다.

관련 정보