삭제되었지만 여전히 애플리케이션에 열려 있는 대용량 파일을 찾는 방법은 무엇입니까? 프로세스에 해당 파일이 열려 있어도 어떻게 삭제할 수 있나요?
상황은 우리가 놀라운 속도로 로그 파일을 채우는 프로세스를 실행하고 있다는 것입니다. 원인을 알고 고칠 수 있어요. 그때까지는 프로세스를 닫지 않고 로그 파일을 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
. "사용된 바이트" 열은줄이다.