2012-02-06 5 views
1

전원 오류 중반 쓰기의 경우에도 파일에 원자 적으로 추가하는 방법을 제공하는 C++로 클래스를 작성하려고합니다.ftruncate()가 비동기입니까?

먼저, 현재 파일 위치 (파일 시작 부분에서 64 바이트 오프셋)를 별도의 저널 파일에 씁니다. 그런 다음 요청 된 데이터를 날짜 파일의 끝에 씁니다. 마지막으로 저널 파일에서 ftruncate() (잘린 크기를 0으로 설정)를 호출합니다.

주요 아이디어는이 클래스가 비어 있지 않은 저널 파일이있는 파일을 여는 경우에는 쓰기가 중단되었음을 알게되고 저널 파일과 fseek에서 마지막 쓰기 위치를 읽을 수 있다는 것입니다 그 자리에. 마지막 부분 쓰기가 손실되지만 파일이 손상되지 않아야합니다.

불행히도 ftruncate()는 비동기식입니다. 실제로, ftruncate 후에 fflush()와 fsync()를 호출하더라도 저널이 많은 쓰기를 수행하는 동안 수백 바이트까지 증가하는 것을 볼 수 있습니다. 항상 궁극적으로는 0으로 끝나지 만 항상 0 또는 8 크기로 보일 것으로 예상됩니다.

ftruncate를 완전히 동기화할 수 있습니까? 또는 저널을 사용하는 더 좋은 방법이 있습니까?

+0

전원 장애가 발생 했습니까? –

+0

일지를 복구하는 동안 전원이 다시 실패하면 어떻게됩니까? –

+1

"저널을 사용하는 더 좋은 방법이 있습니까?" - 복구 요구 사항에 따라 다릅니다. 데이터 파일에 "next-block-should-be-N-bytes"메시지를 쓰면 별도의 저널 (자기 HDD에서 느린 헤드 재배치)이 필요하지 않으므로 복구 상황에서 파일을 처음부터 다시 스캔하거나 블록을 따라 점프하거나 파일의 끝에서 뒤로 스캔 할 때 다음 블록 N 바이트 내용을 다른 내용과 구별 할 수 있습니다. 저널에 대한 메모리 맵핑은 아마 조금 더 우아 할 것이다. –

답변

4

ftruncate()은 파일에서 파일 설명자의 쓰기 오프셋을 변경하지 않습니다. 파일을 열어두고 ftruncate()을 호출 한 후 다음 길이를 쓰는 경우 파일의 오프셋이 여전히 증가하고 있습니다. 쓰면 파일의 길이를 오프셋으로 재설정하고 거기에 바이트를 씁니다.

아마도 ftruncate()을 호출 한 후 lseek(fd, 0, SEEK_SET)으로 전화를 걸면 파일의 다음 기록이 파일의 시작 부분에서 수행됩니다.

+0

은 매력처럼 작동했습니다. :) 감사! – dicroce

+0

그것은 나에게도 효과가있다! – amc

관련 문제