[완료]Linux에서 sync() 또는fsync()의 활용과 iostat
http://opengroup.org/onlinepubs/007908799/xsh/fsync.html
요 사이트에서 발췌한 부분입니다.
(얼마나 정확한 사이트인지도 모르면서;;;)
The fsync() function can be used by an application to indicate that all data for the open file description named by fildes is to be transferred to the storage device associated with the file described by fildes in an implementation-dependent manner. The fsync() function does not return until the system has completed that action or until an error is detected.
The fsync() function forces all currently queued I/O operations associated with the file indicated by file descriptor fildes to the synchronised I/O completion state. All I/O operations are completed as defined for synchronised I/O file integrity completion.
제가 알고 있는 sync 또는 fsync는 메모리에 있는 내용을 디스크에 쓴다는 것으로 알고 있었습니다. 그리고 파일이 디바이스에 다 써지면 리턴된다고 이해했습니다.
fsync()를 코드 앞 뒤에 포함시키고 같은 문장을 1GB 작성하는 프로그램을 돌려봤습니다. 이 코드를 돌리면서 iostat을 찍어보니 프로그램이 끝나도 한참동안 디스크를 쓰고 있습니다.
--
요런 상황이 됩니다.
프로그램 시작
iostat에 파일 쓰는 것이 보이기 시작
프로그램 종료
iostat에서 0이 보이기 시작
--
저의 생각.
iostat : 현재 디스크에 쓰고 있는 상황을 보여준다.
fsync : 디스크에 쓰기 전까지는 리턴되지 않는다.
따라서 코드 앞 뒤에 fsync를 포함하고 파일 쓰기를 하면 iostat에서 파일이 다 써지는 것을 확인한 후에야(BLK_wrtn이 0이 된 후에야) 프로그램이 종료될 것이다.
프로그램시작
iostat에 파일 쓰는 것이 보이기 시작
iostat에 0이 보이기 시작
프로그램 종료
요렇게 될 것이라 생각했습니다.
제가 뭔가 많이 잘 못 이해하고 있는 것 같은데,
고수 분들의 따뜻한 관심과 조언들 부탁드립니다.
man fsync 해보니
(고수는 아니지만 ㅜㅜ)
fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file descriptor fd to the disk device (or
other permanent storage device) where that file resides. The call blocks until the device reports that the transfer has completed. It also flushes metadata information
associated with the file (see stat(2)).
분명 디바이스에서 전송이 완료되었다는 통보가 올 때까지 함수가 block 된다고 되어있습니다.
지금 개운치 않아(?) 하시는 부분이 분명 프로그램이 fsync() call 을 끝내고 종료되었는데도 io가 발생하고 있으니, 위의 내용과 다른 것이 아닌가.. 하는 게 맞는지요..
고수가 아닌 (ㅜㅜ) 제 견해는, iostat 프로세스가 터미널에 report 하는 시간 (타이밍)이 실험 프로그램(1G 텍스트 쓰는 프로그램) 의 시간과 동기화 되지 않아서가 아닐까 싶습니다.
blktrace 등으로 디스크 I/O 트레이스를 확인해 보는게 어떨까요?
실험 프로그램에서는 fsync가 리턴되는 타임을 프린트하고,
blktrace에서 실험 프로그램이 발생시키는 device complete 이벤트 중 마지막 놈의 타임을 비교해보시면 확실히 알 수 있지 않을까요?
beautifool world~!
beautifool world~!
파일을 fopen으로 열어서 그런 것 같기도 하네요 ^^;;
파일을 fopen으로 열고 쓰기도 fwrite로 했는데
그래서 fsync가 동작하지 않은 것 같습니다.
open으로 열어서 write()로 파일쓰기를 하니까
fsync가 잡아 주는군요 ^^;
fopen 으로 연 파일
저 역시 fopen으로 연 파일을 fileno로 변환해서 fsync에 넣어주고 있었는데요
fsync가 block 하지 않는 현상이 발생합니다! 이거 재미있네요.
fflush도 필요한게 아닐까요?
fopen 로열면 c라이브러리 내의 유저영역의 버퍼가 있을것이고
fsync는 커널 함수이므로 fopen에서 사용하는 버퍼는 그대로가 아닐까 합니다.
fflush 로 유저영역의 버퍼를 flush하고 fsync를 호출해줘야 하지 않을까요?
예전글인데 검색하다 나왔길래..
댓글 달기