컴퓨터의 디스크 I/O 연산은 커널 안의 버퍼 캐시나 페이지 캐시를 거칩니다.
따라서 프로세스가 파일에 데이터를 기록하면, 커널은 그 데이터를 커널의 버퍼들 중 하나에 복사해서 내부적인 대기열에 등록해 두고, 적당한 시점이 되면 디스크에 기록합니다.
이 과정에서 데이터가 버퍼에만 있고 디스크에는 아직 기록되지 않은 상태가 될 수 있다. 그러한 경우, 다음과 같은 상황에 문제가 일어날 수 있습니다.
→ 우리는 이러한 디스크 상의 파일 시스템과 버퍼 캐시의 내용의 불일치를 해결하기 위해 sync, fsync, fdatasync 함수를 사용합니다.
두 함수는 모두 파일 시스템의 데이터를 디스크에 안전하게 기록하기 위한 시스템 호출입니다. 운영체제의 파일 시스템 계층과 스토리지 계층 간의 일관성 보장에 중요한 역할을 합니다.
그러나 이 둘은 범위와 동작 방식에서 차이가 있습니다.
#include <unistd.h>
sync();

fd에 대해, 해당 파일의 데이터를 디스크에 강제로 기록합니다.#include <unistd.h>
#include <fcntl.h>
int fd = open("example.txt", O_WRONLY);
write(fd, "data", 4);
fsync(fd); // example.txt 파일에 대해서만 동기화
close(fd);

| 항목 | sync() | fsync(fd) |
|---|---|---|
| 대상 | 전체 시스템 | 특정 파일 |
| 사용 예시 | 시스템 종료 전, 백업 | 중요한 로그, DB 파일 저장 시 |
| 비용 | 큼 | 상대적으로 적음 |
| 일관성 보장 | 시스템 전반 | 파일 단위 |
→ fsync와 sync는 컴퓨터 시스템의 데이터 일관성과 안전성을 확보하기 위해 반드시 필요한 함수 입니다.
특히나 DB, 저널링 파일 시스템, 트랜잭션 처리 등에 있어서 핵심적인 역할을 합니다.
추가로, 리눅스에서 fdatasync() 라는 함수도 있는데, 이는 fsync() 와 비슷하지만 메타데이터는 제외하고 데이터만 동기화합니다. 더 빠른 성능이 필요한 경우 사용됩니다.