유닉스 파일이 손상되었습니다 [닫음]

유닉스 파일이 손상되었습니다 [닫음]

내 로그 중 하나가 실행 중인 프로세스에서 많은 공간을 소비하고 있음을 발견했습니다. logadm을 실행하여 회전할 수 있도록 이 파일을 정리하고 싶습니다. 하지만 난 무엇을 해야할지 모르겠어요

# >MyLog_nohup.out
# ls -lLh MyLog_nohup.out
-rw-r-lr--   1 user     group       72G Jul 30 07:26 MyLog_nohup.out
# du -sh MyLog_nohup.out
480K   MyLog_nohup.out

해제한 후에도 여전히 72G를 소비하고 더 많은 것을 실행하면 빈 줄만 표시됩니다. 이 문제를 어떻게 해결할 수 있습니까?

프로세스를 다시 시작할 여유가 없습니다. 하지만 logadm을 사용하여 이 로그 파일을 회전하고 싶은데 이것이 가능합니까? 시도해 보았지만 무한 루프에서 계속 빈 줄을 처리합니다. 이 파일에 대해 추가 작업을 수행할 때와 동일합니다. 이 문제를 해결할 다른 방법이 있나요?

logrotate의 경우 열린 파일을 처리하는 copytruncate 옵션이 있지만 루프에서 실행되기 때문에 파일에 빈 줄이 있으면 사용할 수 없습니다. 왜 이 파일을 /more/head 볼 수 없는지 아직도 이해가 되지 않습니다!

답변1

실행 중인 프로세스가 열려 있는 한 Linux 및 POSIX 시스템에서는 파일이 손상되지 않습니다.파일 설명자쓰고 있는 파일의 경우 파일을 삭제하거나 이름을 바꾸더라도 계속 쓸 수 있습니다(파일 설명자가 다음과 동일하기 때문).아이노드, 파일 이름이 아님). 특히 logrotate또는 logadm또는 외부 명령 시퀀스는 디스크 공간에 유용한 작업을 수행하지 않습니다.

나는 당신이 Linux를 사용하고 있다고 가정합니다.

프로세스의 pid가 1234인 경우 /proc/1234/구체적으로 나열된 디렉토리를 볼 수 있습니다 /proc/1234/fd/. 읽다공정(5).

아마도 문제가 있는 프로세스를 중지해야 할 것입니다( 끝에 kill -TERMthen을 사용하십시오 . 참조).kill -QUITkill -KILL신호(7)&죽이다(1)) 그런 다음 파일을 삭제하고 마지막으로 더 유용한 로깅을 수행하도록 프로그램을 수정 및/또는 구성한 다음 다시 시작하십시오.

프로그램에서 수행한 모든 계산이 손실되었을 수 있습니다. 그러니 최대한 빨리 중단하고 개선하는 것이 좋습니다.신청 체크포인트, 또는~을 고집하다, 또는 닫는 방법을 추가한 다음 이름을 바꾼 다음 로그 파일을 다시 열고) 향상된 버전의 프로그램을 다시 시작하세요.

너는 읽어야 해고급 Linux 프로그래밍. 프로그램에 여러 가지 버그가 있을 수 있습니다(아마도 로깅과 관련됨). 당신은 사용할 수 있습니다트랙(1)이해하다시스템 호출귀하의 프로세스에 따라 완료되면 사용할 수 있습니다시스템 로그(3)귀하의 (개선된) 프로그램에서.

대부분의 경우 프로그램에 설계 오류가 있을 수 있습니다. 그러니 이제 멈추고, 생각하고, 개선하고, 다시 시작하는 것이 좋습니다. 디스크가 완전히 채워질 때까지 기다리는 것은 도움이 되지 않으며 상황을 더욱 악화시킬 수 있습니다.

향후 테스트 목적으로 일부 설정을 고려할 수 있습니다.디스크 할당량및/또는 일부 리소스 제약(예:제한 설정(2)및 bash ulimit내장).

앞으로는 항상 프로세스를 다시 시작하는 비용을 견딜 수 있도록 프로그램을 설계하십시오. 이를 감당할 수 없다는 것은 항상 큰 실수입니다(특히 백업 전략이 필요하고 백업 전략이 필요한 경우).개정 관리귀하의 소스 코드에서 추천합니다.자식그런 이유로).

답변2

# ls -lLh MyLog_nohup.out
-rw-r-lr-- 사용자 그룹 1개 72G 7월 30일 07:26 MyLog_nohup.out
# du -sh MyLog_nohup.out
480K MyLog_nohup.out

이것은 나에게 희박한 파일처럼 보입니다. 스파스 파일은 효율성을 위해 디스크에 가상 크기(귀하의 경우 72G)를 할당하지만 실제로는 파일에 기록된 데이터만큼 많은 공간(귀하의 경우 480K)을 사용합니다. 가상 크기는 사용된 공간에 포함되지 않습니다(파일을 삭제하면 72G가 확보되지 않고 480k만 확보됩니다).

파일을 읽을 때 빈 줄이 보이는 이유는... 파일 안에는 빈 줄(빈)만 있기 때문입니다. 실제 데이터(사용 가능한 경우)를 보려면 hexdump(1)를 사용해 보십시오. 그러나 의미 있는 출력을 위해서는 파일 형식을 이해하는 도구가 필요합니다(파일을 생성한 프로그램에 해당 도구가 함께 제공되어야 함).

또한 다른 사람들이 지적했듯이 파일이 메모리에 매핑되어 있는 동안에는 파일의 리소스를 회수할 수 없습니다. 매핑을 해제해야 합니다. 즉, 이더넷으로 프로그램을 종료하거나 gdb(1)를 사용하여 이를 시도할 수 있습니다.

pidof <procname>       # find the pid of the process which creates the log file
ls -l /proc/<pid>/fd/  # find the fd pointing to MyLog_nohup.out
gdb -p <pid>           # attach to pid
(gdb) p close(<fd>)    # close fd pointing to log file

그러나 fd가 닫힐 때 프로그램은 로그 파일을 다시 생성하거나 지정되지 않은 방식으로 동작할 수 있으며 "프로세스를 다시 시작할 수 없음"은 위의 내용이 너무 위험할 수 있으므로 로그 파일을 보관하기만 하면 됩니다.

관련 정보