456. WAL 프로토콜 (Write-Ahead Logging)
⚠️ 이 문서는 데이터베이스가 데이터를 하드디스크에 안전하게 저장하면서도 속도를 잃지 않기 위해 지키는 절대 원칙, **"진짜 데이터(Data File)를 건드리기 전에, 무조건 얇은 일기장(Log File)에 먼저 변경 사항을 적어둬라!"라는 'WAL 프로토콜'**을 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: Write-Ahead(앞서서 쓴다) Logging. 디스크에 위치한 실제 데이터 페이지를 갱신하기 전에, 그 변경 사항에 대한 로그(Redo Log, Undo Log)를 디스크에 먼저 기록해야 한다는 규칙이다.
- 가치: 이 원칙을 지키면, DB는 진짜 데이터를 디스크에 쓰는 무거운 작업(Random I/O)을 나중으로 미루고(비동기), 얇은 로그만 빨리 쓰고(Sequential I/O) 사용자에게 "저장 성공!"이라고 대답할 수 있어 엄청난 성능 향상을 얻는다.
- 보장 특성: 이 프로토콜 덕분에 시스템에 정전이 발생하더라도, 디스크에 안전하게 적혀있는 로그 파일을 보고 과거(Undo)나 미래(Redo)로 데이터를 100% 복구(Atomicity, Durability)할 수 있다.
Ⅰ. 개요: 메모리와 디스크의 속도 차이 (Context & Necessity)
우리가 UPDATE 쿼리를 치면 DB는 데이터를 어떻게 처리할까?
하드디스크(데이터 파일)를 직접 뒤져서 글자를 지우고 다시 쓰는 건 너무 느리다.
그래서 DB는 일단 디스크에 있는 데이터를 **메모리(Buffer Pool)**로 퍼 올려서 그 위에서 쓱쓱 고친다. 이 순간 메모리와 디스크의 데이터는 달라진다. (메모리는 최신, 디스크는 옛날 값)
만약 이 상태에서 정전이 나면? 메모리의 최신 데이터는 다 날아간다! 그렇다고 매번 메모리를 고칠 때마다 디스크 원본 파일까지 같이 고치면(Force 방식) 쿼리 하나 칠 때마다 3초씩 걸릴 것이다.
이 딜레마를 해결한 천재적인 타협안이 WAL 프로토콜이다. "원본 파일을 고치는 건 너무 무거우니까 나중에 한가할 때 몰아서 하자. 대신, '내가 뭘 고쳤는지'만 얇은 공책(로그 파일)에다가 엄청 빨리 휘갈겨 적고(WAL) 그걸로 저장 끝났다고 치자!"
📢 섹션 요약 비유: WAL은 **'가게의 장부 정리'**와 같습니다. 손님이 물건을 살 때마다 물건의 바코드를 찍고 창고 재고 리스트(Data File)를 고치는 건 너무 바쁩니다. 그래서 일단 계산대 앞의 '임시 수첩(Log File)'에 "A과자 팔림"이라고 먼저 후다닥 적어두고(Write-Ahead), 나중에 저녁에 가게 문을 닫고 창고 정리를 몰아서 하는 방식입니다.
Ⅱ. WAL 프로토콜의 2대 절대 원칙 ★
데이터의 원자성(Undo)과 영속성(Redo)을 지키기 위한 수학적 약속이다.
1. Undo (원자성) 규칙
- "메모리의 더러운(수정된) 데이터를 디스크에 덮어쓰기 전에, 반드시 Undo 로그를 먼저 디스크에 안전하게 적어둬야 한다."
- 이유: 만약 원본 데이터를 디스크에 덮어써 버렸는데 트랜잭션이 취소(Rollback)되면? Undo 로그가 디스크에 없으면 옛날 값을 알 수 없어서 영영 복구할 수 없게 되기 때문이다.
2. Redo (영속성) 규칙
- "트랜잭션에 Commit 도장을 찍어주기 전에, 반드시 Redo 로그를 먼저 디스크에 안전하게 적어둬야 한다."
- 이유: Commit 도장을 찍고 "저장 완료!"라고 대답했는데 정전이 났다. Redo 로그가 디스크에 없으면, 진짜 원본 파일에는 아직 안 적힌 데이터라서 방금 Commit 한 작업이 증발해 버리기 때문이다.
Ⅲ. 강제 쓰기(Force)와 노포스(No-Force)의 춤
WAL은 디스크 I/O 전략의 꽃이다.
- Force (강제): Commit 할 때 진짜 데이터 파일(Data File)까지 무조건 강제로 덮어쓰는 방식. 너무 느려서 실무에서 절대 안 쓴다.
- No-Force (노포스): Commit 해도 진짜 데이터 파일은 안 건드린다. 나중에 한가할 때(체크포인트) 천천히 쓴다. (WAL의 핵심)
- Steal (스틸): 트랜잭션이 끝나지도 않았는데(Uncommitted), 메모리가 꽉 차면 어쩔 수 없이 디스크 원본 파일에 덮어써 버리는 방식. (이때 Undo 로그가 없으면 큰일 남)
현대의 거의 모든 RDBMS(Oracle, MySQL)는 [No-Force + Steal] 방식을 채택하고, 이를 WAL 프로토콜로 통제하여 성능과 복구라는 두 마리 토끼를 다 잡는다.
┌──────────────────────────────────────────────────────────────┐
│ WAL 프로토콜 (Write-Ahead Logging) 작동 흐름 시각화 │
├──────────────────────────────────────────────────────────────┤
│ │
│ [ 👨💻 UPDATE 실행 및 COMMIT ] │
│ │
│ 1️⃣ 🧠 메모리 (버퍼 풀)에서 데이터 수정 (A=10 -> A=20) │
│ │
│ 2️⃣ 📝 디스크의 [로그 파일(Redo/Undo)]에 "A를 20으로 고쳤음" 기록 │
│ ◀── (이게 WAL! 진짜 데이터보다 로그가 항상 '앞서서' 기록됨) │
│ │
│ 3️⃣ 📢 사용자에게 "저장 완료(Commit)!" 응답 발송 │
│ │
│ ... (몇 분 뒤) ... │
│ │
│ 4️⃣ 💾 디스크의 [진짜 데이터 파일(Data File)]에 20으로 슬쩍 덮어씀. │
└──────────────────────────────────────────────────────────────┘
Ⅳ. 결론
"가장 중요한 일은 가장 가벼운 방식으로 처리하라." 데이터베이스 엔진이 아무리 똑똑한 인덱스를 가지고 있어도, 쓰기 작업(Insert/Update)이 느리면 시스템 전체가 마비된다. WAL 프로토콜은 하드디스크가 '여기저기 찾아다니며 쓰는 것(Random Write)'은 끔찍하게 느리지만 '끝에다가 계속 이어 붙이는 것(Sequential Write)'은 100배 이상 빠르다는 물리적 한계를 가장 완벽하게 우회한 소프트웨어 아키텍처다. 우리는 이 보이지 않는 일기장 덕분에 1초에 수천 건의 결제를 하면서도 안심하고 잠들 수 있다.
📌 관련 개념 맵
- 관련 특성: 원자성(A), 영속성(D) (440번 문서)
- 보완 기술: Checkpoint (체크포인트 - 457번 문서)
- 로그의 종류: Redo Log (455번 문서), Undo Log (454번 문서)
- 하드웨어 원리: Random I/O vs Sequential I/O
👶 어린이를 위한 3줄 비유 설명
- WAL은 숙제 다 했다고 엄마한테 거짓말(?)을 치고 나중에 진짜 숙제를 하는 기술이에요.
- 내가 숙제를 다 하려면 3시간이 걸려요(디스크 쓰기). 근데 3시간 동안 엄마가 기다리시면 화를 내시겠죠?
- 그래서 일단 일기장(로그 파일)에 "오늘 숙제 3쪽 풀었음"이라고 딱 1초 만에 적어서 엄마한테 보여드리고(Commit), 진짜 숙제는 나중에 밤에 몰래 천천히 푸는(No-Force) 거랍니다!