457. 체크포인트 (Checkpoint) 회복 범위 단축
⚠️ 이 문서는 장애가 났을 때 리두 로그(Redo Log)를 비디오 테이프처럼 처음부터 끝까지 다 틀어보려면 복구 시간이 몇 달씩 걸리는 문제를 해결하기 위해, 주기적으로 "여기까지는 완벽하게 디스크에 저장했음!"이라는 깃발(Checkpoint)을 꽂아두어 복구 시간을 획기적으로 줄여주는 최적화 기술을 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 메모리(Buffer)에 쌓여있는 더러운 데이터(Dirty Page, 아직 원본 파일에 안 써진 데이터)들을 하드디스크의 진짜 데이터 파일(Data File)에 강제로 내려쓰는(Flush) 이벤트다.
- 가치: 장애가 났을 때, 체크포인트 깃발 이전의 로그들은 무시하고 **깃발 이후에 쌓인 로그들만 다시 실행(Redo)**하면 되므로 데이터베이스 복구 시간(Recovery Time)을 극단적으로 단축한다.
- 딜레마: 체크포인트를 너무 자주 하면 시스템이 평소에 너무 느려지고(디스크 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가 발생한다.
- 로깅 확정: 현재까지 메모리에 쌓여있던 모든 로그(Redo Log)를 디스크에 강제로 먼저 쓴다. (WAL 원칙 준수)
- 데이터 확정: 메모리 버퍼 풀에 쌓여있던 '더러운 데이터(Dirty Pages, 수정된 데이터)'들을 진짜 데이터 파일(Data File)에 통째로 덮어쓴다.
- 깃발 꽂기: 로그 파일과 컨트롤 파일에 "나 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줄 비유 설명
- 동생이 레고 성을 만들 때, 엄마가 "다 만들 때까지 설명서(로그) 잃어버리지 마!"라고 했어요.
- 성이 100층짜리인데, 무너지면 1층부터 다시 설명서 보고 만들어야 하니까 끔찍하잖아요?
- 그래서 10층을 만들 때마다 "여기까지 완성!" 하고 본드로 꽉 붙여놓는 게(체크포인트) 좋아요. 그럼 나중에 11층에서 무너져도 10층부터만 다시 설명서를 보고 만들면 되니까요!