Dirty Page와 Writeback: 메모리 변경을 디스크에 반영하는 방식
Dirty Page의 의미와 페이지 교체, 데이터베이스 버퍼 풀, Linux Writeback 매개변수 및 성능 영향까지 정리한다.
2026-08-14 · 최초 발행 2025-12-30
메모리에서 바뀐 페이지는 바로 버릴 수 없다
페이지 교체가 필요한 시점에 메모리의 내용이 디스크와 다르면, 그 페이지는 바로 제거할 수 없다. 프로세스의 쓰기 연산으로 변경된 정보를 담고 있기 때문이다. 이런 페이지를 Dirty Page 또는 Modified Page라고 한다.
페이지에 쓰기가 발생하면 메모리의 내용은 바뀌고, 페이지 테이블 엔트리의 Dirty Bit가 설정된다. 이후 해당 페이지가 교체 대상이 되었을 때 Clean Page라면 곧바로 삭제할 수 있지만, Dirty Page는 먼저 디스크에 저장해야 한다. 이 저장 과정이 Writeback이다.
메모리는 휘발성이지만 디스크는 비휘발성 저장소다. 따라서 변경 사항을 디스크에 반영하지 않은 채 Dirty Page를 삭제하면 데이터가 손실된다. 물리 메모리에서 내보낼 때 더티 페이지는 .swp 확장자로 저장되며, 필요하면 다시 로드할 수 있다. Linux에서는 /var/swap, /swap 같은 위치의 스왑 파티션 또는 파일을 전용 공간으로 사용한다.
Dirty Bit는 페이지 테이블 엔트리의 플래그다. 값이 1이면 변경된 Dirty 상태이고, 0이면 변경되지 않은 Clean 상태다. 이 플래그는 하드웨어가 자동으로 설정한다. 페이지는 Clean Page와 Dirty Page 외에도 Read-Only Page, Shared Page 상태로 관리될 수 있다.
데이터베이스의 버퍼 풀에서 보는 Dirty Page
데이터베이스에서 Dirty Page는 트랜잭션이 종료하지 않은 상태에서 변경된 데이터를 담은 버퍼 풀 페이지를 가리킨다. 이 페이지 역시 디스크의 내용과 다르고, 커밋 전 상태일 수 있다.
트랜잭션이 시작된 뒤 UPDATE, INSERT, DELETE가 실행되면 버퍼 풀의 페이지가 수정되고 Dirty Page가 생성된다. 커밋 전에는 변경 내용이 버퍼 풀에만 존재하므로 롤백할 가능성이 있다. 커밋 뒤에는 WAL(Write-Ahead Logging)과 Flush를 통해 지속성을 보장하며, Dirty Page는 Clean Page로 전환된다.
버퍼 풀은 메모리 캐시로 디스크 I/O를 줄인다. Dirty Page 비율이 높으면 Checkpoint 부하가 증가하고, 낮으면 디스크 I/O가 증가한다. Checkpoint는 Dirty Page를 주기적으로 Flush하고 트랜잭션 로그를 동기화해 복구 시간을 단축하며 시스템 안정성을 뒷받침한다.
Writeback이 시작되는 시점
Writeback은 메모리에 쌓인 Dirty Page를 디스크에 기록하는 과정이다. 지연 쓰기로 디스크 I/O를 늦추고, 여러 페이지를 묶어 처리해 I/O를 줄이는 방식이다.
가용 물리 메모리가 부족해져 dirty_background_ratio 한계에 도달하면 백그라운드 Writeback이 시작된다. Dirty Page가 dirty_expire_centisecs로 정한 시간보다 오래 메모리에 머무른 경우에도 Writeback 대상이 된다. 지정된 최소 페이지 개수 이상이 누적됐을 때도 배치 처리 효율을 위해 저장할 수 있다.
sync 명령, fsync 시스템 콜, 애플리케이션 요청, 시스템 종료는 강제 동기화가 필요한 경우다.
Linux 2.6 커널에서는 pdflush가 Dirty Page를 자동 저장하는 백그라운드 커널 쓰레드였다. 이 데몬은 일정 간격으로 깨어나 dirty_background_ratio를 확인하고 조건이 맞으면 Writeback을 실행한 뒤 대기한다. Linux 3.0+에서는 pdflush 대신 블록 디바이스별 per-BDI flusher threads가 이 역할을 맡아 병렬 처리와 성능 향상을 지원한다.
Linux에서 조정하는 Writeback 기준
dirty_background_ratio는 전체 메모리 대비 Dirty Page 비율을 기준으로 백그라운드 Writeback을 시작하는 임계값이다. 기본값은 10%이며 시스템마다 다르다.
/proc/sys/vm/dirty_background_ratio
이 비율을 낮추면 Writeback이 자주 일어나 메모리 여유는 커지지만 I/O는 증가한다. 높이면 Writeback 빈도와 I/O는 줄어들 수 있으나 메모리 압박이 커질 수 있다.
dirty_ratio는 전체 메모리 대비 Dirty Page의 최대 비율이며, 초과하면 쓰기 프로세스가 블로킹되고 동기 Writeback이 수행된다. 기본값은 20%이며 시스템마다 다르다.
/proc/sys/vm/dirty_ratio
두 값의 차이는 Writeback 방식에 있다. dirty_background_ratio는 백그라운드 Writeback의 기준이고, dirty_ratio는 프로세스 블로킹을 수반하는 동기 Writeback의 기준이다.
dirty_expire_centisecs는 Dirty Page의 만료 시간을 1/100초 단위로 지정한다. 기본값은 3000 (30초)이다.
/proc/sys/vm/dirty_expire_centisecs
이 시간을 넘긴 Dirty Page는 Writeback 대상으로 선택된다. 값을 짧게 하면 동기화 빈도와 I/O가 증가하지만 데이터 안전 측면에 유리하며, 길게 하면 동기화는 줄고 성능은 향상될 수 있으나 데이터 위험은 커진다.
캐싱 효과와 누적 비용의 균형
Dirty Page는 메모리 쓰기를 빠르게 처리하고 디스크 I/O를 지연시켜 응답 시간을 단축하며 처리량을 높인다. 여러 쓰기를 한 번에 처리하는 배치 방식은 디스크 I/O와 헤드 이동을 줄이고, 동일 블록의 쓰기를 병합하면 I/O 요청과 디스크 부하도 감소한다.
반대로 Dirty Page가 과도하게 쌓이면 가용 메모리가 부족해지고 페이지 교체가 잦아져 시스템이 느려질 수 있다. Writeback 지연은 디스크 I/O 대기와 프로세스 블로킹으로 이어져 응답 시간을 늘리고 처리량을 낮춘다. 대량의 Dirty Page를 Flush하는 Checkpoint는 디스크 I/O 스파이크와 시스템 정지(Stall)를 만들 수 있으며, 시스템 크래시 시에는 메모리에 있던 Dirty Page 손실과 복구 시간 증가, 일관성 문제가 발생할 수 있다.
워크로드에 맞춰 조정할 항목
dirty_background_ratio는 워크로드에 맞추고, dirty_ratio는 메모리 크기를 고려하며, dirty_expire_centisecs에는 데이터 중요도를 반영한다. 물리 메모리를 늘리면 Dirty Page를 위한 여유 공간이 생겨 Writeback 빈도를 줄일 수 있다. SSD는 빠른 쓰기 속도와 랜덤 I/O 성능으로 Writeback 부담을 낮춘다.
데이터베이스에서는 버퍼 풀 크기, Checkpoint 간격, WAL 크기, 트랜잭션 배치 처리가 조정 대상이다. 애플리케이션에서는 명시적 fsync 호출, 트랜잭션 크기, 쓰기 패턴, 캐시 활용을 함께 검토한다.
# 현재 더티 페이지 확인
cat /proc/meminfo | grep Dirty
# 매개변수 확인
cat /proc/sys/vm/dirty_background_ratio
cat /proc/sys/vm/dirty_ratio
cat /proc/sys/vm/dirty_expire_centisecs
# 매개변수 변경
echo 5 > /proc/sys/vm/dirty_background_ratio
echo 10 > /proc/sys/vm/dirty_ratio
일반적인 권장 설정은 SSD에서 dirty_background_ratio=5, dirty_ratio=10이고, HDD에서는 dirty_background_ratio=10, dirty_ratio=20이다. 대용량 메모리에서는 낮은 비율을 사용하며, 데이터베이스에서는 짧은 expire 시간을 둔다.