💡 핵심 인사이트
데이터베이스가 메모리(버퍼 풀)에만 데이터를 썼다가 갑자기 정전으로 서버가 꺼지면 데이터가 모두 증발합니다.
이를 막기 위해 발명된 기법이 **WAL(Write-Ahead Logging)**입니다. "실제 디스크 데이터를 고치기 전에, 수정 내역을 담은 로그(Log)부터 무조건 먼저 디스크에 안전하게 적어둔다"는 절대 원칙입니다.
Ⅰ. 복구(Recovery)의 딜레마
앞서 [50. 버퍼 풀]에서 성능을 위해 변경된 데이터(더티 페이지)를 메모리에만 머물게 하다가 나중에 디스크로 플러시(Flush)한다고 했습니다. 문제 발생: 트랜잭션이 성공적으로 커밋(Commit)되었는데, 더티 페이지가 디스크로 기록되기 전에 서버의 전원 코드가 뽑히면 어떻게 될까요? 고객은 결제 완료 메시지를 받았는데, DB를 다시 켜보면 결제 내역이 날아가는 대형 사고가 발생합니다.
매번 커밋할 때마다 데이터 블록 전체를 디스크에 쓰자니 I/O 비용이 너무 커서 성능이 폭락합니다. 이 모순을 해결하는 것이 로깅 엔진입니다.
Ⅱ. WAL (Write-Ahead Logging) 프로토콜
데이터베이스 시스템의 ACID(특히 영속성, Durability)를 보장하기 위한 가장 핵심적인 원칙입니다. 직역하면 **"쓰기(Write)보다 로그(Log)를 먼저(Ahead) 기록한다"**입니다.
동작 메커니즘
- 사용자가 데이터를 수정하면, 버퍼 풀의 데이터(더티 페이지)를 변경합니다.
- 커밋(Commit) 요청이 들어옵니다.
- DBMS는 무거운 '데이터 블록'을 디스크에 쓰는 대신, "A계좌에서 B계좌로 100원 이동함"이라는 아주 가벼운 '로그 레코드(Redo Log)'만 디스크의 로그 파일에 순차적으로(Sequential) 빠르게 기록합니다. (이때 디스크 헤더가 여기저기 움직일 필요 없이 끝에 이어 붙이기만 하면 되므로 매우 빠릅니다.)
- 로그가 디스크에 기록되는 순간, DBMS는 사용자에게 "커밋 성공!" 응답을 보냅니다. (데이터 파일은 아직 수정 안 됨)
- 나중에 여유가 생기면 메모리의 더티 페이지를 데이터 파일(디스크)로 플러시합니다.
Ⅲ. 장애 발생 시의 복구 메커니즘
만약 위 과정 4번과 5번 사이(로그는 썼지만 데이터는 안 쓴 상태)에 정전이 발생했다면?
- Redo (재실행, 복구): DB 서버가 다시 켜질 때 로깅 엔진이 디스크에 안전하게 남아있는 로그 파일을 읽어 들입니다. "아하, 커밋은 떨어졌는데 데이터 파일에 반영이 안 됐네?" 로그에 적힌 내역을 토대로 메모리를 예전 상태로 똑같이 재연(Redo)하여 데이터를 완벽히 살려냅니다.
- Undo (취소, 롤백): 반대로 트랜잭션 도중에 뻗었다면, Undo 로그를 보고 쓰다 만 데이터를 원래 상태로 되돌립니다.
📢 섹션 요약 비유: WAL은 식당의 **주문 장부(Log)**와 같습니다. 주방장이 요리(데이터 디스크 기록)를 완성하기 전에, 웨이터는 일단 손님의 주문 내역을 장부에 적고 펜을 내려놓는 작업(WAL)부터 무조건 먼저 완료합니다. 그래야 중간에 불이 꺼져도, 불 켜진 뒤 장부를 보고 못 나간 요리를 다시 만들어(Redo) 낼 수 있기 때문입니다.