444. 영속성 (Durability)과 로깅

⚠️ 이 문서는 데이터베이스가 사용자에게 "저장 완료!"라고 대답한 직후에 서버에 벼락이 떨어져서 하드디스크 전원이 나가더라도, 방금 저장한 데이터가 우주 끝까지 영원히 지워지지 않음을 보장하기 위해 '로그 파일'에 목숨을 거는 '영속성'의 원리를 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 트랜잭션이 성공적으로 완료(COMMIT)되었다면, 그 결과는 시스템에 치명적인 장애가 발생하더라도 절대로 손실되지 않고 영구적으로 보존되어야 한다는 원칙이다.
  2. 딜레마: COMMIT을 칠 때마다 진짜 데이터 파일(Data File)에 직접 찾아가서 데이터를 쓰면 디스크 I/O 때문에 속도가 너무 느려서 DB가 멈춰버린다.
  3. 보장 기법: 그래서 DB는 진짜 데이터 파일에 쓰기 전에, 일단 무조건 **'Redo Log(리두 로그)'**라는 가벼운 일기장에 변경 사항을 먼저 후다닥 적어두는 WAL (Write-Ahead Logging) 기법을 사용하여 속도와 영속성을 동시에 잡아낸다.

Ⅰ. 개요: 벼락 맞은 은행 서버 (Context & Necessity)

당신이 인터넷 뱅킹으로 100만 원을 송금하고, 화면에 **"이체 완료 (COMMIT)"**라는 팝업을 확인했다. 그런데 1초 뒤에 은행 데이터센터에 벼락이 떨어져 서버가 모두 셧다운 되었다. 10분 뒤 서버가 복구되었는데, 내 돈 100만 원이 증발해버렸다. 은행 측은 "아직 하드디스크에 저장하는 중이었는데 전원이 나갔네요"라고 변명한다.

이런 일이 은행에서 한 번이라도 발생하면 그 은행은 파산한다. 그래서 데이터베이스는 **"내가 COMMIT이라고 대답했다면, 무슨 일이 있어도 그 데이터는 영원히(Durability) 지켜줄게"**라고 목숨 걸고 약속한다.

📢 섹션 요약 비유: 영속성은 **'계약서 공증'**과 같습니다. 구두로만 "계약 완료!"라고 외치는 건 정전(장애)이 나면 잊어버릴 수 있습니다. 하지만 영속성은 도장을 찍는 즉시, 그 계약서 사본을 **'절대 타지 않는 금고(로그 파일)'**에 복사해 두는 것과 같아서 은행 건물이 불타도 계약 내용은 살아남습니다.


Ⅱ. 영속성을 보장하는 마법: Redo Log ★

DB 엔진은 속도를 위해 데이터를 '메모리(Buffer Cache)'에 올려놓고 작업한다. COMMIT을 친다고 해서 메모리에 있는 데이터를 무거운 디스크(Data File)에 즉시 덮어쓰지 않는다. (너무 느리니까)

그럼 전원이 나가면 어떻게 복구할까? 해답은 **Redo Log(다시 하기 로그)**에 있다.

  1. 사용자가 1만 원을 입금하고 COMMIT을 누른다.
  2. DB는 진짜 데이터 파일을 건드리지 않고, 디스크의 구석에 있는 Redo Log 파일에 "A 계좌에 +1만 원 하셈"이라고 한 줄만 아주 빠르게(Sequential Write) 휘갈겨 쓴다. (이것을 WAL 기법이라고 함)
  3. 로그를 무사히 썼으므로, 사용자에게 "성공!"이라고 대답한다.
  4. 이때 서버가 펑! 터진다.
  5. (서버 재부팅 후) DB 회복 시스템이 켜진다.
  6. 회복 시스템: "어? 아까 메모리에서 디스크로 데이터 옮겨 적다가 죽었네? Redo Log 가져와!"
  7. Redo Log를 쭉 읽어보면서, 디스크에 미처 반영되지 못한 "+1만 원" 작업을 그대로 똑같이 다시(Redo) 실행해서 데이터를 완벽하게 살려낸다.

Ⅲ. WAL (Write-Ahead Logging) 철학

현대의 모든 RDBMS가 영속성과 속도를 둘 다 잡기 위해 쓰는 궁극의 아키텍처다.

  • 원칙: "진짜 데이터베이스 파일(Data File)을 수정하기 전에, 무조건 로그 파일(Log File)에 먼저 기록해야 한다."
  • 이유: 로그 파일은 뒤에다 계속 덧붙여 쓰기(Append-only)만 하면 되기 때문에 디스크 바늘이 왔다 갔다 할 필요가 없어서 속도가 100배 빠르기 때문이다.
┌──────────────────────────────────────────────────────────────┐
│           영속성(Durability)을 보장하는 WAL 작동 과정 시각화              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ [ 👨‍💻 사용자 ] "COMMIT!"                                       │
│                                                              │
│ 1️⃣ [ 🧠 메모리 (Buffer) ] 데이터 수정 (속도 빠름)                    │
│                                                              │
│ 2️⃣ [ 📝 Redo Log (Disk) ] "방금 수정한 거 로그에 적었음!" (빠른 쓰기)    │
│    ──▶ (여기까지만 성공하면 사용자에게 "COMMIT 완료" 응답을 줌!)        │
│                                                              │
│ 💥 (이때 서버가 죽어도, Redo Log가 디스크에 있으니 나중에 100% 복구됨)   │
│                                                              │
│ 3️⃣ [ 💾 Data File (Disk) ] "나중에 쉴 때 메모리 데이터를 디스크로        │
│                           천천히 덮어써야지~ (Checkpoint)"       │
└──────────────────────────────────────────────────────────────┘

Ⅳ. 결론

"가장 가벼운 기록이, 가장 무거운 신뢰를 만든다." 영속성은 성능(Performance)과 정면으로 충돌하는 성질이다. 데이터가 절대 날아가지 않게 하려면 디스크에 매번 강제로 써야 하는데(fsync), 그러면 서버가 끔찍하게 느려지기 때문이다. 이를 극복하기 위해 천재 아키텍트들은 Undo Log(원자성)와 Redo Log(영속성)라는 투 트랙(Two-track) 로깅 시스템을 고안해 냈다. 이 로그 기반 아키텍처 덕분에 우리는 디스크의 물리적 한계를 딛고, 초당 수만 건의 결제를 처리하면서도 "내 돈은 절대 증발하지 않는다"는 확고한 믿음을 가질 수 있게 되었다.


📌 관련 개념 맵

  • 관련 특성: 원자성(A), 일관성(C), 고립성(I) (440번 문서)
  • 대칭 로그: Undo Log (언두 로그 - 롤백을 위해 '과거'를 적어두는 로그, 441번 문서)
  • 핵심 인프라: WAL (Write-Ahead Logging), Checkpoint (체크포인트)
  • 관련 장애: 스토리지 디스크 자체가 물리적으로 부서진 경우는 Redo Log로도 못 살린다. (이땐 백업본과 아카이브 로그가 필요함)

👶 어린이를 위한 3줄 비유 설명

  1. 영속성은 내가 그린 그림일기를 '불에 타지 않는 금고'에 넣어서 영원히 보관하는 거예요.
  2. 하지만 두꺼운 진짜 일기장을 매일 밤 금고에 넣고 빼는 건 너무 무겁고 힘들죠. (DB 성능 저하)
  3. 그래서 얇은 쪽지(Redo Log)에 "오늘 그림일기 내용"만 빨리 적어서 금고에 던져 넣고 잡니다! 나중에 진짜 일기장이 찢어져도, 금고 속 쪽지들을 모아서 똑같이 다시 그릴 수 있답니다!