457. 체크포인트 (Checkpoint) 회복 범위 단축

⚠️ 이 문서는 장애가 났을 때 리두 로그(Redo Log)를 비디오 테이프처럼 처음부터 끝까지 다 틀어보려면 복구 시간이 몇 달씩 걸리는 문제를 해결하기 위해, 주기적으로 "여기까지는 완벽하게 디스크에 저장했음!"이라는 깃발(Checkpoint)을 꽂아두어 복구 시간을 획기적으로 줄여주는 최적화 기술을 다룹니다.

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

  1. 본질: 메모리(Buffer)에 쌓여있는 더러운 데이터(Dirty Page, 아직 원본 파일에 안 써진 데이터)들을 하드디스크의 진짜 데이터 파일(Data File)에 강제로 내려쓰는(Flush) 이벤트다.
  2. 가치: 장애가 났을 때, 체크포인트 깃발 이전의 로그들은 무시하고 **깃발 이후에 쌓인 로그들만 다시 실행(Redo)**하면 되므로 데이터베이스 복구 시간(Recovery Time)을 극단적으로 단축한다.
  3. 딜레마: 체크포인트를 너무 자주 하면 시스템이 평소에 너무 느려지고(디스크 I/O 과다), 너무 가끔 하면 장애 시 복구 시간이 너무 길어지므로(장애 대기 시간 증가) 이 주기를 조율하는 것이 DBA의 핵심 역량이다.

Ⅰ. 개요: 비디오 테이프 빨리 감기 (Context & Necessity)

WAL 프로토콜(456번 문서) 덕분에 DB는 엄청나게 빨라졌다. 데이터는 대충 로그에만 적어두고, 나중에 한가할 때 디스크에 덮어쓰면 되니까.

  • 문제 발생: 데이터베이스가 1년 동안 안 죽고 잘 돌아갔다. 1년 동안 쌓인 리두 로그 파일이 수백 기가바이트다.
  • 대참사: 딱 1년 1일 차에 정전이 났다.
  • 복구 과정: 원칙대로라면? 1년 치 리두 로그를 1월 1일 것부터 12월 31일 것까지 처음부터 끝까지 다시 다 실행(Redo)해 봐야 한다. 복구하는 데만 한 달이 걸린다.

이 바보 같은 짓을 막기 위해 **체크포인트(Checkpoint)**가 존재한다. DB는 1시간에 한 번씩 "자, 지금까지 메모리에 있던 데이터들 다 디스크 원본 파일에 완벽하게 덮어썼어!"라고 로그에 [Checkpoint] 도장을 쾅 찍어둔다. 정전이 나면? 어제 찍은 도장 이후의 1시간 치 로그만 Redo 하면 된다.

📢 섹션 요약 비유: 체크포인트는 게임의 **'자동 저장(Auto-Save)'**과 같습니다. 게임 오버가 되었을 때 처음 튜토리얼부터 다시 깨야 한다면 미쳐버리겠지만, 10분 전에 찍어둔 세이브 포인트가 있다면 거기서부터만 다시 하면 되니까 금방 복구할 수 있죠.


Ⅱ. 체크포인트 발생 시의 3단계 동작 ★

체크포인트 이벤트가 발동하면 내부적으로 묵직한 디스크 I/O가 발생한다.

  1. 로깅 확정: 현재까지 메모리에 쌓여있던 모든 로그(Redo Log)를 디스크에 강제로 먼저 쓴다. (WAL 원칙 준수)
  2. 데이터 확정: 메모리 버퍼 풀에 쌓여있던 '더러운 데이터(Dirty Pages, 수정된 데이터)'들을 진짜 데이터 파일(Data File)에 통째로 덮어쓴다.
  3. 깃발 꽂기: 로그 파일과 컨트롤 파일에 "나 2026년 4월 10일 15시 정각에 체크포인트 찍었어"라고 시스템 번호(SCN)를 기록한다.

Ⅲ. 회복(Recovery) 시나리오: Redo 할까? Undo 할까?

가장 중요한 시험 출제 포인트다. 체크포인트([CP])와 정전([Fail]) 시점을 기준으로 트랜잭션의 운명이 갈린다.

  • T1: [CP] 이전에 Commit 됨 $\rightarrow$ 이미 디스크에 완벽하게 박혀있음. 아무것도 안 해도 됨.
  • T2: [CP] 전에 시작해서, [Fail] 전에 Commit 됨 $\rightarrow$ 메모리엔 있었지만 디스크엔 못 들어갔을 수 있음. 무조건 **Redo(다시 실행)**해서 디스크에 박아줘야 함.
  • T3: [CP] 이후에 시작해서, [Fail] 전에 Commit 됨 $\rightarrow$ 무조건 Redo(다시 실행).
  • T4: [CP] 전에 시작해서, [Fail] 시점까지 Commit을 못 함 $\rightarrow$ [CP] 때 억지로 디스크에 쓰레기 데이터가 들어갔을 수 있음. 무조건 **Undo(취소/롤백)**해서 빼내야 함.
  • T5: [CP] 이후에 시작해서, [Fail] 시점까지 Commit을 못 함 $\rightarrow$ 무조건 Undo(취소).
┌──────────────────────────────────────────────────────────────┐
│           체크포인트 기준 트랜잭션(T1~T5) 복구 원리 시각화             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ 시간  ────────────────────── [Checkpoint] ────────── [Fail]  │
│ T1: [시작]-----(Commit)                                        │
│ T2:       [시작]----------------(Commit)                     │
│ T3:                                 [시작]---(Commit)        │
│ T4:             [시작]----------------------------(죽음)     │
│ T5:                                     [시작]------(죽음)   │
│                                                              │
│ ★ 복구 전략:                                                  │
│   - T1: 아무것도 안 함 (이미 안전)                               │
│   - T2, T3: Redo (로그 보고 다시 실행해서 살려냄)                  │
│   - T4, T5: Undo (로그 보고 과거로 롤백해서 지워버림)               │
└──────────────────────────────────────────────────────────────┘

Ⅳ. 결론

"안전과 성능 사이의 가장 치열한 줄다리기." 체크포인트 주기를 '1분'으로 짧게 잡으면 장애 시 1분 만에 시스템이 복구된다(MTTR 감소). 하지만 1분마다 디스크를 미친 듯이 긁어대야 하므로 평상시 서비스 속도가 최악이 된다. 반대로 '1시간'으로 잡으면 평소엔 날아다니지만, 정전 한 번에 복구 시간이 1시간이 걸려 회사 게시판에 사과문이 올라가게 될 것이다. 데이터베이스 아키텍트(DBA)가 하는 일 중 가장 예술적인 영역이 바로 비즈니스의 성격에 맞춰 이 체크포인트의 주기를 튜닝하는 일이다.


📌 관련 개념 맵

  • 관련 특성: 영속성 (Durability - 444번 문서), 원자성 (Atomicity - 441번 문서)
  • 기반 프로토콜: WAL (Write-Ahead Logging - 456번 문서)
  • 내부 아키텍처: Buffer Pool, Dirty Page, LSN/SCN (System Change Number)
  • 옵션: Fuzzy Checkpoint (서비스가 멈추지 않게 조금씩 천천히 백그라운드에서 체크포인트를 수행하는 현대적 기술)

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

  1. 동생이 레고 성을 만들 때, 엄마가 "다 만들 때까지 설명서(로그) 잃어버리지 마!"라고 했어요.
  2. 성이 100층짜리인데, 무너지면 1층부터 다시 설명서 보고 만들어야 하니까 끔찍하잖아요?
  3. 그래서 10층을 만들 때마다 "여기까지 완성!" 하고 본드로 꽉 붙여놓는 게(체크포인트) 좋아요. 그럼 나중에 11층에서 무너져도 10층부터만 다시 설명서를 보고 만들면 되니까요!