로그 프로그램이 어떻게 삭제 된 파일에 계속 로그를 기록 할 수 있습니까?


12

로부터 유닉스 파워 툴, 제 3 판은 : 대신 파일을 제거, 그것을 비우기 섹션 :

활성 프로세스에 파일이 열려있는 경우 (로그 파일에서는 드문 일이 아님) 파일을 제거하고 새 파일을 작성해도 로깅 프로그램에는 영향을 미치지 않습니다. 해당 메시지 는 더 이상 연결되지 않은 파일로 계속 이동합니다 . 파일을 비우면 연결이 끊어지지 않으므로 로깅 프로그램에 영향을주지 않고 파일을 지 웁니다.

( 중점 광산 )

프로그램이 삭제 된 파일에 계속 기록하는 이유를 이해하지 못합니다. 파일 디스크립터 항목이 프로세스 테이블에서 제거되지 않기 때문입니까?

답변:


11

파일을 삭제하면 실제로 파일에 대한 링크 (아이 노드)가 제거됩니다. 누군가 이미 해당 파일을 열어 놓은 경우 파일 설명자를 유지합니다. 파일은 디스크에 남아있어 공간을 차지하며 파일에 액세스 할 수 있으면 쓰거나 읽을 수 있습니다.

unlink기능은 POSIX하여이 동작으로 정의된다 :

파일의 링크 수가 0이되고 프로세스가 파일을 열지 않은 경우 파일이 차지하는 공간을 비우고 파일에 더 이상 액세스 할 수 없게됩니다. 마지막 링크가 제거 될 때 하나 이상의 프로세스가 파일을 연 경우 unlink ()가 리턴되기 전에 링크가 제거되지만 파일에 대한 모든 참조가 닫힐 때까지 파일 컨텐츠 제거가 연기 됩니다.

그 행동으로 인해이 조언. 데몬은 파일을 열어 놓았으며 파일이 삭제되었음을 알지 못합니다 (특별히 모니터링하지 않는 한 드문 경우). 기존 파일 디스크립터에 계속 쓸 수 있습니다. 디스크의 공간을 계속 차지하지만 작성하는 메시지를 볼 수 없으므로 실제로 최악의 상태입니다. 두 세계의. 대신 파일을 길이가 0으로 자르면 공간이 즉시 비워지고 파일을 볼 수있는 새 메시지 끝에 새 메시지가 추가됩니다.

결국, 데몬이 종료되거나 close파일 을 사용하면 공간이 비워집니다. 그 어느 누구도 그 동안 파일을 열 수 없습니다 ( Linux/proc/x/fd/... 와 같은 시스템 고유의 반사 인터페이스를 통해서 제외). 또한 다음을 보장합니다.

파일의 링크 카운트가 0 인 경우, 파일과 연관된 모든 파일 디스크립터가 닫히면 파일이 차지하는 공간이 비워지고 파일에 더 이상 액세스 할 수 없게됩니다.

따라서 디스크 공간을 영구적으로 잃지 않지만 파일을 삭제해도 아무런 효과가 없으며 새 메시지에 액세스 할 수 없습니다.


1
사용자 (여기서는 root라고하자)가 연결을 해제하려고하면 /proc/x/fd/y어떻게됩니까? 프로세스가 파일 디스크립터에 쓰지 못하게됩니까, 아니면 잘못된 조작입니까?
nanofarad

@hexafraction /proc/*/fd/*은 실제 파일에 대한 심볼릭 링크이므로 제거해도 파일이 삭제되지 않습니다. 나는 당신이 실험 해 볼 것을 제안합니다 :) (물론 생산 시스템이 아닙니다!)
Ruslan

1
@MichaelHomer 아마도 파일에서 연결이 해제되면 파일 설명자가있는 파일 프로세스가 동일한 경로에서 다시 연결될 수 있는지 프로세스에서 알 수 있습니다. 이것은 때때로 유용 할 수 있습니다.
lgeorget

@hexafraction 글쎄, 이것들은 단지 프로세스 상태와 객체를 (파일 시스템 공간에서) 표현한 것입니다. 파일 시스템 공간에서 해당 표현을 제거하면 실제 프로세스에는 아무런 영향이 없습니다. 해당 프로세스 (또는 다른 프로세스)가 해당 표현에 의존하지 않는 한 아무 것도 발생하지 않습니다. 확실하지 당신이 사용할 수있는 rm내부 즉시 /proc또는 /sys어쨌든 시스템에 의해 전원에게받지 않고.
David Tonhofer

@lgeorget 어떻게 이루어 집니까?
Michael

8

바로 그거죠.

파일은 세 부분으로 구성됩니다.

  • 내용, 즉 평평한 바이트 배열로 디스크 어딘가에 작성되거나 즉석에서 생성됩니다.
  • 인덱스 노드아이 노드 데이터 구조 채워 커널에 의해 사용되는 짧은. 파일에 대한 모든 메타 데이터 (크기, 권한 등)와 파일 내용의 위치에 대한 포인터도 포함합니다.
  • 하나 개 이상의 디렉토리 항목 으로 조작 위치입니다, 경로/home/user/personal_file이 그 내용을 수정 파일을 사용할 수있는 핸들 역할을, 등의 메타 데이터를 변경

파일을 열면 운영 체제에 대한 경로가 제공되고 inode에 직접 핸들을 반환합니다. 파일 디스크립터라고하는이 핸들을 사용하여 원하는대로 (또는 최소한 OS에서 허용 한대로) 파일을 조작 할 수 있습니다.

inode를 직접 삭제할 수 없으므로 OS를 삭제해야하는 경로 를 제공 해야합니다. 따라서 파일을 삭제하려는 경우 디렉토리 항목 만 삭제합니다. 파일에 다른 디렉토리 항목이있는 경우 파일에 계속 액세스 할 수 있으며 파일에 액세스 할 수없는 경우에도 파일 디스크립터가 파일을 가리키는 동안 해당 inode는 삭제되지 않습니다. @MichaelHomer의 답변은이 주제에 대해 더 기술적이고 상세합니다.


4

다른 두 가지 답변은 문제를 잘 설명합니다. 파일에 대한 모든 디렉토리 링크 열려있는 모든 파일 설명자가 사라질 때까지 파일이 "삭제"되지 않습니다 .

이것을 피하려면 사용하는 것이 좋습니다.

> /var/log/bigfile

대신에

rm -f /var/log/bigfile

내용을 삭제하는 대신 0 바이트로 재설정하기 때문에 내용을 계속 볼 수 있습니다.

파일을 삭제하고 / proc / fd 파일 시스템이있는 Linux에있는 경우 계속 사용할 수 있습니다

> /proc/12345/fd/3

파일의 내용을 0으로 설정하십시오 (12345는 프로세스 ID이고 3은 큰 파일의 fd 번호라고 가정). 디스크가 가득 차서 어떤 이유로 든 로그 파일을 작성하는 프로세스를 종료 할 수없는 경우 이는 생명의 은인이 될 수 있습니다.


> /var/log/bigfile파일의 기존 데이터를 제거하지만 프로그램 쓰기를 중지하지는 않습니다. 그것이 옳은 상황은 거의 없습니다. 들어가는 것은 나쁜 습관이라고 말하고 싶습니다. 파일을 삭제하려면을 사용하십시오 rm. 작성중인 프로그램을 중지하려면 삭제하기 전후에 프로그램을 종료하거나 작성을 중지하십시오.
Gilles 'SO- 악마 그만해'

1
@Giles,이 주제는 프로그램이 여전히 파일을 연 상태에서 삭제해도 도움이되지 않는다는 사실에 관한 것입니다. 디스크가 일부 프로그램 무례한 행동 때문에 가득 차 있다면 syslogd채우기 /var/log/messages, > /var/log/messages살인보다 훨씬 더 나은 선택이다 syslogd. 물론 문제가 무엇인지 분석하는 것을 막을 수는 없습니다.
Guntram Blohm은 Monica
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.