19.1 복구 개요 (Recovery Overview)
복구 관리자는 "끝난 일은 남기고(durability), 안 끝난 일은 지운다(atomicity)".
ACID 중 복구 관리자의 역할
복구 관리자(recovery manager)는 ACID 중 Atomicity(원자성)와 Durability(영속성)를 책임집니다. 나머지 Isolation(격리성)·Consistency(일관성)는 동시성 제어(concurrency control)가 담당합니다.
- Atomicity (원자성)
- 트랜잭션은 전부(all) 반영되거나 전혀(nothing) 반영되지 않는다. 미완료 트랜잭션의 흔적은 UNDO로 지운다.
- Durability (영속성)
- 커밋(commit)된 트랜잭션의 결과는 장애가 나도 사라지지 않는다. 디스크에 미반영된 부분은 REDO로 재실행한다.
저장 매체 (Storage)
데이터 페이지는 두 곳에 존재합니다. 실패는 실행 중 어느 시점에든 발생할 수 있습니다.
- Buffer Cache (휘발성)
- Volatile. DRAM 상의 버퍼 캐시. 페이지 Pi, Pj의 사본을 두고 빠르게 읽고 쓴다. 전원이 꺼지면 소실.
- Storage (비휘발성)
- Non-volatile. HDD/SSD 등 영속 저장장치. 페이지 Pi, Pj의 진짜 본체. 전원이 꺼져도 보존.
버퍼의 수정(dirty page)이 언제 디스크로 내려가느냐가 복구 전략(Steal/Force)을 결정한다.
Redo = Durability(커밋했는데 디스크에 안 내려간 수정을 재실행), Undo = Atomicity(커밋 안 했는데 디스크로 새어 나간 수정을 되돌림). 이 한 쌍이 19장 전체를 관통합니다.
19.2 장애 분류 (Failure Classification)
장애의 종류가 곧 복구 동작(undo / redo)을 결정한다.
Transaction failure 트랜잭션 장애
한 트랜잭션이 정상 완료에 실패. 논리 오류, 교착상태(deadlock)로 인한 강제 종료(kill), 사용자 rollback 등.
복구: 해당 트랜잭션의 변경을 UNDO로 되돌린다(rollback).
System failure 시스템 장애
OS/DBMS 오류, 정전(power) 등으로 시스템 전체가 멈춤. 휘발성 버퍼 내용이 소실되고, 페이지의 atomic write가 보장되지 않을 수 있다.
복구: 재시작 시 REDO + UNDO를 모두 수행한다.
Media failure 보충
디스크 자체가 물리적으로 손상되어 비휘발 저장장치의 데이터가 깨지는 경우.
본 강의 범위 밖. 아카이브 덤프·원격 백업으로 대응(아래 보충 참고).
디스크 손상(media failure)은 로그만으로 복구할 수 없습니다. 주기적 archival dump와 별도 사이트의 remote backup(원격 백업)으로 대비하며, 본 강의의 핵심 범위(transaction/system failure)에는 포함되지 않습니다.
동기 그림 — 무엇을 지키고 무엇을 지워야 하나
Crash(붕괴) 선을 기준으로, 그 전에 커밋한 트랜잭션은 살리고(durability), 진행 중이던 트랜잭션은 지운다(atomicity).
T1·T2·T3는 crash 전에 commit → durable(REDO 대상). T4·T5는 진행 중 → abort/undo(UNDO 대상).
장애 종류 → 복구 동작 매핑: Transaction failure → UNDO, System failure → REDO + UNDO, Media failure → 범위 밖(백업).
19.3 Steal / Force 버퍼 정책
버퍼의 dirty page를 "언제" 디스크로 내리느냐가 UNDO/REDO 필요 여부를 결정한다.
두 축: Steal & Force
- Force at Commit
- 커밋 시점에 그 트랜잭션이 수정한 페이지를 강제로 디스크에 기록한다. → 디스크에 All 반영 → Durability 자동 확보(REDO 불필요).
- No-Force
- 커밋해도 디스크에 강제로 내리지 않는다(나중에). → 미반영 수정 가능 → REDO 필요.
- No-Steal
- 커밋 안 된(uncommitted) dirty page를 디스크로 내보내지 않는다. → 디스크엔 Nothing(미커밋 흔적 없음) → UNDO 불필요.
- Steal
- 버퍼가 부족하면 미커밋 dirty page도 디스크로 훔쳐서(steal) 내려보낼 수 있다. → 미커밋 수정이 디스크에 셀 수 있음 → UNDO 필요.
No-Steal은 모든 dirty page를 커밋까지 RAM에 잡아둬야 해 메모리 한계로 비현실적. Force는 커밋마다 무작위 쓰기(random write)라 비효율 → 대부분의 DBMS는 Steal + No-Force를 택한다.
🖱️ Steal × Force 매트릭스 토글
셀을 클릭하면 필요한 로그(UNDO/REDO)와 성능 특성을 확인할 수 있습니다.
Steal → UNDO 필요(미커밋 stolen page의 old value를 기억해 되돌리기 = atomicity).
No-Force → REDO 필요(디스크 미반영 커밋 수정을 재실행 = durability).
실무 = Steal + No-Force = UNDO + REDO 둘 다 (Desired / 가장 빠름).
19.4 로그 (Log) · LSN
데이터베이스 = 디스크의 페이지 + 로그. 로그는 신뢰할 수 있는 중복(redundant) 기록이다.
LSN과 pageLSN
모든 페이지 업데이트는 DRAM의 log buffer에 로그 레코드를 만들고, 그 로그의 일련번호 LSN(Log Sequence Number)을 해당 페이지의 pageLSN으로 저장합니다. 즉 "이 페이지는 어디까지의 로그가 반영되었는가"를 pageLSN이 가리킵니다.
로그는 별도 디스크에 순차 쓰기(sequential write)로, 변경분(diff)만 최소로 기록 → 빠르고 신뢰성 높음.
로그의 신뢰성
DRAM의 페이지는 unreliable(휘발). 로그는 reliable한 중복 기록으로, 두 가지 보증을 만듭니다.
- Redo → committed 트랜잭션의 durability 보장
- Undo → uncommitted 트랜잭션의 atomicity 보장
로그 레코드 포맷 (Log record format)
XID = 트랜잭션 ID. pageID/offset/length = 어느 페이지의 어디를 얼마나 바꿨는가. old data는 UNDO용, new data는 REDO용입니다. (제어 정보를 제외한 per-page diff 단위로 기록.)
전통적 교재(Silberschatz)의 로그 레코드 <Ti, X, V1, V2>는 위 포맷의 축약입니다: Ti = XID, X = 데이터 항목(pageID/offset 위치), V1 = old data, V2 = new data. 트랜잭션 경계는 <Ti start>, <Ti commit>, <Ti abort>로 기록합니다.
로깅 종류 (Logging types) — Trade-off
Physical logging
바이트/이미지 단위(before-image, after-image)로 기록. 단순하지만 로그량이 가장 큼.
Logical logging
고수준 연산을 기록. 예: Insert A, r. 로그량은 적지만 재실행(apply) 시간이 큼.
Physio-logical logging
페이지 지정 + 논리 연산. 예: Insert A page10, r. 둘의 절충(실무 표준, ARIES).
| 기준 | Physical | Physio-logical | Logical |
|---|---|---|---|
| 로그량 (Log volume) | 가장 큼 | 중간 | 가장 작음 |
| 적용 시간 (Apply time) | 가장 빠름 | 중간 | 가장 느림 |
정리: Log volume Physical > Physio > Logical · Apply time Logical > Physio > Physical.
DO – UNDO – REDO
DO
정상 실행: OLD → NEW로 변경하며 로그를 남긴다.
UNDO
되돌리기: NEW → OLD. undo log(old data) 사용. Atomicity.
REDO
재실행: OLD → NEW. redo log(new data) 사용. Durability.
Undo = 아리아드네의 실타래(왔던 길을 되짚어 빠져나옴) · Redo = 헨젤과 그레텔의 빵 부스러기(흔적을 따라 다시 진행). undo는 뒤로, redo는 앞으로.
고전 복구 기법 두 가지: Deferred modification(지연 갱신)은 커밋 전까지 디스크 갱신을 미뤄 UNDO가 필요 없음(REDO만). Immediate modification(즉시 갱신)은 커밋 전에도 디스크에 쓸 수 있어 UNDO와 REDO가 모두 필요. 현대 DBMS(Steal+No-Force)는 immediate modification에 해당합니다.
19.4+ 로그 기반 복구: Deferred vs Immediate 보충
고전 교과서(Silberschatz)의 두 가지 log-based recovery 기법 — 갱신을 "언제" 디스크에 반영하느냐가 UNDO/REDO 필요 여부를 결정한다.
고전 로그 레코드 (Classic log records)
X = 데이터 항목(data item), V1 = old value(갱신 전), V2 = new value(갱신 후). <Ti start>/<Ti commit>/<Ti abort>는 트랜잭션 경계 레코드입니다. V1은 UNDO용, V2는 REDO용.
Deferred database modification 지연 갱신
트랜잭션이 partial commit(부분 완료) 시점까지 모든 write를 디스크에 반영하지 않고 지연합니다. 로그에는 new value만 기록 → <Ti, X, V>.
- old value가 없으므로 UNDO 불요 — 미커밋 트랜잭션은 디스크를 더럽힌 적이 없다.
- REDO만 필요.
redo(Ti) 수행 조건: 로그에 <Ti start>와 <Ti commit>이 둘 다 있을 때 → X에 V를 정순으로 다시 쓴다.
Immediate database modification 즉시 갱신
트랜잭션이 active(실행 중)일 때도 갱신을 DB에 바로 반영합니다. 로그에는 old + new 모두 기록 → <Ti, X, V1, V2>.
- 미커밋 갱신이 디스크에 새어 나갈 수 있으므로 UNDO 필요.
- 커밋 후 미반영분 복구를 위해 REDO도 필요 → 둘 다.
undo(Ti): <Ti start>는 있고 <Ti commit/abort>이 없을 때 → 로그를 역순으로 읽어 X ← V1 복원.
redo(Ti): <Ti start>·<Ti commit> 둘 다 있을 때 → 정순으로 X ← V2 재적용.
Deferred = REDO만 (new value만 로깅, undo 불요) · Immediate = UNDO + REDO 둘 다 (old+new 로깅). 현대 DBMS(Steal+No-Force)는 Immediate에 해당.
undo와 redo는 여러 번 적용해도 결과가 동일합니다(idempotent). redo는 X에 V2를 "쓰는" 연산이므로 두 번 써도 V2, undo는 X에 V1을 "쓰는" 연산이라 두 번 써도 V1. 덕분에 복구 도중 다시 crash가 나도 처음부터 다시 시작하면 되며, 이미 적용된 갱신을 중복 적용해도 안전합니다.
Worked example — 구체 로그와 3가지 crash 시점
아래 로그(immediate modification, A=1000·B=2000·C=700에서 시작)에 대해 crash 시점별 복구를 정리한다.
| Crash 시점 | 로그 상태 | UNDO-list | REDO-list | 복구 동작 / 결과 |
|---|---|---|---|---|
① <T0,B,..> 직후 |
T0 start 있음, commit 없음 | {T0} | {} | undo(T0) 역순: B←2000, A←1000 A=1000, B=2000, C=700 |
② <T1,C,..> 직후 |
T0 commit 있음, T1 start만 있음 | {T1} | {T0} | redo(T0): A←950, B←2050 / undo(T1): C←700 A=950, B=2050, C=700 |
③ <T1 commit> 후 |
T0·T1 모두 commit | {} | {T0, T1} | redo(T0): A←950,B←2050 / redo(T1): C←600 A=950, B=2050, C=600 |
🔁 로그 재생 시뮬레이터 보충
★ 실제 로그 레코드 기반 ★ crash 지점을 선택하면 각 트랜잭션을 UNDO/REDO로 분류하고 A·B·C 최종값을 계산합니다.
로그 레코드를 클릭해 crash 지점을 선택하세요(그 레코드까지 디스크/로그에 기록되었다고 가정).
19.6+ 체크포인트 기반 복구 보충
로그를 처음부터 다 스캔하지 않도록, 가장 최근 checkpoint부터 거꾸로 읽으며 UNDO/REDO list를 구성한다(§19.6 보강).
<checkpoint L> 로그
L = checkpoint 시점에 active(활성)였던 트랜잭션 목록. 이 레코드를 로그에 남기기 전, 메모리의 모든 로그를 stable storage로 flush합니다.
복구 시 로그 끝에서 역방향으로 스캔하다 가장 최근 <checkpoint L>을 만나는 순간, 그 이전 트랜잭션의 분류는 (L에 든 것 외에는) 끝낼 수 있습니다.
UNDO/REDO list 결정 규칙
- 역방향 스캔으로 undo-list(commit/abort 없는 active TX)와 redo-list(commit 있는 TX)를 구성.
<checkpoint L>도달 시: L에 없으면서 checkpoint 이전에 이미 commit된 트랜잭션은 무시 가능(이미 디스크 반영 가정).- L에 든 트랜잭션과 checkpoint 이후 시작된 트랜잭션만 계속 추적.
Worked example — checkpoint로 redo/undo list 결정
로그(시간순). T0은 checkpoint 이전 commit, checkpoint 당시 active = {T1}.
| 트랜잭션 | 상태 | 분류 | 이유 |
|---|---|---|---|
| T0 | checkpoint 이전 commit | 무시 | checkpoint L에 없음 + 이미 commit → 디스크 반영 가정 |
| T1 | L에 속함, 이후 commit | REDO | L에 포함되어 추적 대상, commit 존재 → redo-list |
| T2 | checkpoint 이후 start, commit 없음 | UNDO | active loser → undo-list (역순 복원) |
복구 = 최근 checkpoint부터 역방향 스캔으로 undo-list/redo-list 구성. checkpoint 이전 commit + L에 없음 → 무시. 덕분에 로그 전체를 읽지 않아 복구 시간이 짧아진다.
19.5 WAL & Commit
로그 먼저, 데이터 나중 — 두 개의 "먼저" 규칙이 atomicity와 durability를 만든다.
WAL Protocol (UNDO용)
Write-Ahead Logging. 어떤 페이지를 디스크에 (over)write하기 전에, log buffer의 undo log를 그 페이지의 pageLSN까지 디스크로 flush해야 한다.
→ 미커밋 수정이 디스크에 새어 나가더라도(Steal), 그것을 되돌릴 undo log가 이미 디스크에 있으므로 atomicity를 지킬 수 있다.
Force-log-at-commit (REDO용)
트랜잭션의 commit log record가 log disk에 영속 저장된 뒤에야 진짜로 commit으로 간주한다.
→ 커밋한 트랜잭션의 redo log가 디스크에 보장되어, 데이터 페이지가 아직 안 내려갔어도 REDO로 복구 가능 → durability.
커밋마다 fsync는 성능 병목 → group commit: 여러 트랜잭션의 로그 페이지를 모아 한 번에 flush.
🛡️ WAL 규칙 데모
WAL을 지키면 안전하게 복구되고, 어기면 atomicity가 깨진다.
WAL 준수 시: undo log를 먼저 flush한 뒤 Pi를 쓴다.
WAL 규칙: 데이터 페이지 디스크 쓰기 전에 undo log를 pageLSN까지 flush(= UNDO/atomicity 보장).
Force-log-at-commit: commit record가 영속 저장된 후 commit(= REDO/durability 보장), group commit으로 가속.
19.6 체크포인트 (Checkpoint)
복구 시간을 줄이기 위해 "여기까지는 정리됐다"는 표식을 주기적으로 남긴다.
왜 필요한가
No-Force 정책 때문에 이미 커밋한 트랜잭션이 더럽힌(dirty) 페이지가 버퍼에 계속 쌓입니다. REDO로 복구는 가능하지만, 로그를 처음부터 다 읽으면 복구 시간이 길어집니다(시간 = 돈).
→ 주기적 checkpoint로 복구 시작점을 끌어올려 복구 시간을 최소화합니다.
BEGIN / END_CHECKPOINT
- BEGIN_CHECKPOINT
- 체크포인트 시작 표식.
- END_CHECKPOINT
- 두 테이블을 로그에 기록: TX table(활성 트랜잭션)과 dirty page table(더티 페이지 목록).
Fuzzy checkpoint
- 다른 트랜잭션은 계속 실행된다(시스템을 멈추지 않음).
- 기록되는 테이블은 BEGIN 시점 기준만 정확하다.
- dirty page를 강제로 디스크에 force하지 않는다.
- 완료된 checkpoint record의 LSN을 master record에 저장한다 → 복구 시 여기부터 시작.
Fuzzy checkpoint는 시스템을 멈추지 않고(non-quiescent) 찍으며, master record가 "복구를 어디서부터 시작할지(last checkpoint LSN)"를 가리킨다.
19.7 ARIES — 3단계 복구
Algorithm for Recovery and Isolation Exploiting Semantics — 현대 DBMS 복구의 표준(golden standard).
ARIES는 last checkpoint(master record가 가리키는 지점)부터 복구를 시작해, crash 시점의 상태를 파악하고 로그 전체를 다시 재생(replay history)한 뒤, 커밋되지 않은 트랜잭션(예: T4·T5)을 되돌립니다. 세 단계는 방향(forward/backward)이 시험의 핵심입니다.
① Analysis forward
Checkpoint → End of Log(앞으로). 어떤 트랜잭션이 활성/커밋이었는지, 어떤 페이지가 dirty였는지 상태를 파악.
② Redo forward
First update potentially lost → End of Log(앞으로). history를 그대로 재생(replay)해 crash 직전 상태를 복원.
③ Undo backward
End of Log → Start of oldest in-progress TX(뒤로). uncommitted 트랜잭션을 되돌림.
Analysis(forward) → Redo(forward) → Undo(backward). 처음 두 단계는 앞으로, 마지막 Undo만 뒤로. 보조 구조: LSN·pageLSN·dirty page table·TX table·master record.
⏱️ ARIES 3단계 타임라인 위젯
버튼으로 각 단계를 짚어 가며 화살표 방향과 범위를 확인하세요.
단계 버튼을 눌러 보세요.
🔁 Undo / Redo 복구 시뮬레이터
★ 핵심 ★ 각 트랜잭션의 commit 여부를 바꾸고 "복구 실행"을 눌러 REDO/UNDO 목록이 어떻게 바뀌는지 확인하세요.
각 트랜잭션 칩을 눌러 commit 여부를 토글한 뒤 복구를 실행하세요.
ARIES는 Undo 단계에서 되돌리는 보상 작업도 CLR(보상 로그 레코드)로 기록합니다. 덕분에 undo 도중 다시 crash가 나도 이미 되돌린 작업을 반복하지 않습니다(undo의 멱등성·효율성 보장).
19.7+ ARIES 자료구조 & 알고리즘 심화 보충
ARIES가 "정확히" 어떤 자료구조로 repeat history와 효율적 undo를 달성하는가.
핵심 자료구조 (Key data structures)
| 구조 | 정의 | 역할 |
|---|---|---|
| LSN Log Sequence Number | 로그 레코드의 단조증가(monotonic) 주소. | 레코드 순서·위치 식별. 다른 모든 구조가 LSN을 가리킨다. |
| PageLSN | 각 페이지에 적용된 최신 LSN(페이지 안에 저장). | Redo 중 LSN ≤ PageLSN이면 이미 반영됨 → skip. |
| PrevLSN | 같은 트랜잭션의 직전 로그 LSN(역방향 체인). | Undo 시 한 트랜잭션의 로그를 거꾸로 따라간다. |
| DPT Dirty Page Table | PageID → RecLSN(그 페이지를 더럽힌 첫 갱신의 LSN). | Redo 시작점 결정: DPT의 최소 RecLSN. |
| TT Transaction Table | TxnID → LastLSN, status(active/committed). | crash 시 active "loser" 트랜잭션 식별 → undo 대상. |
| Master record | 안정 저장장치의 고정 위치. | 가장 최근 checkpoint의 LSN을 가리킴 → 복구 시작점. |
Undo 중 수행한 보상 갱신(compensating update)을 redo-only 레코드로 기록합니다(되돌릴 일이 없으므로 undo 정보 불요). CLR은 UndoNextLSN 필드로 "다음에 undo할 지점"을 가리킵니다. → undo 도중 다시 crash가 나도 이미 보상한 갱신을 반복하지 않고 UndoNextLSN부터 이어서 진행 → undo의 멱등성·효율성 보장.
3단계 정밀 정의 (Three passes, precisely)
① Analysis forward
최근 checkpoint → 로그 끝까지 forward 스캔. DPT·TT 재구성. Redo 시작점 = DPT의 최소 RecLSN. Undo 대상 = crash 시 active였던 loser 트랜잭션.
② Redo forward
최소 RecLSN → 끝까지 forward. repeat history: 페이지가 DPT에 있고 RecLSN ≤ LSN 이며 PageLSN < LSN인 갱신만 재적용(나머지는 이미 반영 → skip). loser/winner 구분 없이 모두 재생.
③ Undo backward
끝 → 역방향. loser 트랜잭션을 PrevLSN 체인 따라 되돌리며 CLR 기록. CLR의 UndoNextLSN으로 재crash에도 안전.
Worked example — 작은 로그의 redo/undo 판정
checkpoint 직후 DPT={P1:RecLSN 10}, 로그가 아래와 같고 crash 시 active(loser)={T2}라 하자. P1의 디스크상 PageLSN=10이라 가정.
| LSN | 로그 레코드 | 페이지 | Redo? | Undo? |
|---|---|---|---|---|
| 10 | <T1, P1, ...> | P1 | skip (PageLSN 10 ≥ 10) | — (winner) |
| 20 | <T1 commit> | — | — | — |
| 30 | <T2, P1, ...> | P1 | REDO (PageLSN 10 < 30) | UNDO → CLR(40) |
| — | ⚡ CRASH (T2 미commit) | — | — | T2 = loser |
Redo는 winner/loser 구분 없이 repeat history(LSN 30 재적용, LSN 10은 PageLSN로 skip). 그 뒤 Undo가 loser T2의 LSN 30을 PrevLSN 따라 되돌리며 CLR(LSN 40, UndoNextLSN→T2의 이전 LSN)을 남긴다.
ARIES의 checkpoint는 보통 fuzzy(non-quiescent): 트랜잭션을 멈추지 않고 DPT/TT만 로그에 기록하며 dirty page를 force하지 않습니다. 그래서 Analysis 단계가 checkpoint의 DPT/TT를 출발점으로 삼아 crash 직전 상태를 재구성해야 합니다(§19.6 fuzzy checkpoint 참조).
PageLSN으로 redo skip · RecLSN(DPT)으로 redo 시작점 · PrevLSN으로 undo 체인 · CLR + UndoNextLSN으로 undo 중 재crash 안전.
19.9 비휘발성 저장장치 손실 복구 보충
Loss of Nonvolatile Storage — 디스크 자체가 깨지면(media failure) 로그만으로는 복구 불가. 주기적 archival dump가 필요하다.
Archival dump (전체 백업)
DB 전체를 stable storage(테이프/별도 디스크)로 복사하고 로그에 <dump> 레코드를 남깁니다. 가장 단순한 형태는 모든 트랜잭션을 멈추고(quiescent) 떠 두는 방식입니다.
SQL dump도 이 범주 — DB 상태를 한 시점으로 떠내는 백업.
Fuzzy dump (무중단)
checkpoint의 fuzzy 아이디어를 그대로 적용 — 트랜잭션을 멈추지 않고 백업을 뜹니다. 백업 중 진행된 갱신은 로그로 보정합니다.
가용성(availability)이 높아 운영 시스템에 적합.
① 가장 최근 dump를 복원(restore) → ② dump 이후의 로그를 REDO로 재적용 → 최신 상태 복구. (transaction/system failure와 달리 dump가 출발점이 된다.)
19.10 원격 백업 시스템 보충
Remote Backup Systems — 한 사이트가 통째로 죽어도 서비스를 잇는 고가용성(high availability) 구조.
구성
Primary site(주 사이트)가 트랜잭션을 처리하고, 로그를 지리적으로 떨어진 remote backup(hot spare) site로 전송합니다. backup은 로그를 받아 계속 redo하며 primary 상태를 따라갑니다.
primary 장애 시 backup이 제어를 이양(takeover)받아 서비스를 이어갑니다.
설계 이슈 (Design issues)
- Failure 탐지(detection): primary 죽음과 통신 단절을 구분하기 위해 다중 통신선(multiple links) 사용.
- 제어 이양(takeover): backup이 수신한 로그를 redo한 뒤 새 primary로 승격. (네트워크 분단 시 split-brain 주의.)
- 복구 시간(recovery time): hot(로그 즉시 redo, 즉시 인계) / warm / cold spare 순으로 인계 속도 차이.
- commit 시점 durability 등급(아래).
Commit durability 등급 — 가용성 vs 지속성 트레이드오프
| 등급 | commit 인정 조건 | 지속성 | 가용성/지연 |
|---|---|---|---|
| One-safe | primary에 로그가 영속되면 즉시 commit. | 낮음 backup 누락분 손실 가능 | 가장 빠름 |
| Two-very-safe | primary + backup 둘 다 로그 영속돼야 commit. | 가장 높음 | 한 사이트만 살아도 멈춤 가용성 최악 |
| Two-safe | 둘 다 살아있으면 양쪽 영속 후 commit, backup이 죽으면 primary만으로 진행. | 높음 | 실용적 절충 권장 |
Two-very-safe는 지속성 최고지만 한쪽만 죽어도 commit 불가(가용성 ↓). Two-safe는 둘 다 살면 양쪽, backup 장애 시 primary만 → 지속성과 가용성의 실용적 균형(보통 채택).
19.8 핵심 정리
Logging × Recovery 2×2 — 한 장으로 정리하는 복구.
| No-Steal | Steal | |
|---|---|---|
| Force | No-UNDO, No-REDO Trivial · 가장 느림 |
UNDO Force = 느림 |
| No-Force | REDO | UNDO + REDO Desired · 가장 빠름 (실무) |
Steal → UNDO · No-Force → REDO · Steal+No-Force → 둘 다(실무). Redo=durability, Undo=atomicity.
로그/LSN → WAL(undo) + Force-log-at-commit(redo) → checkpoint(복구 시작점) → ARIES Analysis(→) · Redo(→) · Undo(←).