로그·체크포인트와 장애 회복
커밋·디스크 기록·장애의 시점을 구분하고 추상 redo/undo 모델을 InnoDB 회복·백업의 역할과 연결합니다.
트랜잭션의 성공 응답을 받았다고 해서 모든 변경 페이지가 이미 데이터 파일에 기록된 것은 아닙니다. DBMS는 메모리의 변경과 영구 저장을 조율하면서 장애 뒤에도 확정된 사실을 복원해야 합니다. 이 본문은 회복 원리를 설명하며 실제 서버를 강제 종료하는 실험을 요구하지 않습니다.
어떤 상태를 복원할 것인가
활동 중인 트랜잭션은 읽기·변경을 수행합니다. 마지막 작업을 마친 부분 완료는 아직 영구적인 커밋이 보장된 상태가 아닙니다. 커밋 기록과 필요한 내구성 처리가 끝나야 완료로 다룰 수 있습니다. 실패하면 변경을 철회하고 필요에 따라 새 트랜잭션으로 재시도합니다.
프로그램 오류로 한 트랜잭션만 실패한 경우, 전원 중단으로 메모리 내용이 사라진 경우, 데이터 장치 자체가 손상된 경우는 복구 재료가 다릅니다. ROLLBACK, 서버의 로그 기반 장애 회복, 백업 복원과 이후 로그 적용을 같은 작업으로 취급하지 않습니다.
쓰기 전 로그와 redo/undo
WAL(Write-Ahead Logging)의 핵심은 변경된 데이터 페이지를 영구 저장하기 전에 그 변경을 회복할 로그를 먼저 영구 저장하는 순서입니다. 버퍼의 데이터를 수정하기 전에 반드시 매번 디스크 로그를 쓰는 단순 순서라는 뜻은 아닙니다.
redo는 필요한 변경을 다시 적용하고, undo는 확정되지 않은 변경을 되돌립니다. 다음은 설명용 값 로그이며 InnoDB 내부 로그 파일의 실제 형식이 아닙니다.
| 순서 | 사건 | 논리적 잔액 | 장애 때 확인할 근거 |
|---|---|---|---|
| 0 | 초기 잔액 | 10 | 기존 저장 상태 |
| 1 | T1: 10→7 | 7 | 변경 로그 |
| 2 | T1 커밋 | 7 | 커밋·내구성 근거 |
| 3 | T2: 7→5 | 5 | 미완료 변경 로그 |
| 4 | T2 커밋 전에 장애 | 회복 대상 | T1 확정, T2 미확정 |
이 단순 모델의 최종 확정 값은 7입니다. 데이터 페이지가 오래된 10이면 확정된 변경을 다시 적용할 근거가 필요하고, 미완료 5가 기록될 수 있는 설계면 이를 철회할 근거도 필요합니다. 실제 회복의 redo 범위는 “커밋한 트랜잭션만 재실행”이라는 한 문장보다 복잡합니다.
교과서 회복 모델의 전제
지연 갱신의 단순 모델은 미커밋 데이터를 데이터 파일로 내리지 않으므로 주로 redo를 설명합니다. 즉시 갱신은 커밋 전 페이지가 저장될 수 있어 undo가 필요할 수 있습니다. 이 차이를 판단하려면 두 페이지 정책을 먼저 정의해야 합니다.
- steal: 아직 커밋하지 않은 트랜잭션의 변경 페이지도 데이터 파일에 저장할 수 있습니다. 메모리 공간을 확보하는 데 도움이 되지만 장애 때 미확정 값이 디스크에 남을 수 있습니다. no-steal은 이를 허용하지 않습니다.
- force: 커밋 완료 전에 그 트랜잭션이 바꾼 데이터 페이지를 모두 영구 저장합니다. no-force는 커밋 때 모든 데이터 페이지의 저장을 강제하지 않으므로 확정 로그가 있어도 데이터 파일에는 이전 값이 남을 수 있습니다.
다음 표는 데이터 페이지의 값만 고려한 단순 회복 모형입니다. 필요한 로그·저장 순서가 지켜지고 페이지 쓰기 손상 등 다른 문제가 없다는 전제입니다. 실제 DB의 로그 재생 범위나 메타데이터 복구 전체를 판정하는 표는 아닙니다.
| 페이지 정책 | 미커밋 값이 데이터 파일에 남을 수 있나? | 커밋 값이 아직 데이터 파일에 없을 수 있나? | 이 모형에서 필요한 회복 방향 |
|---|---|---|---|
| no-steal + force | 아니요 | 아니요 | 두 이유에 따른 undo·redo는 불필요 |
| steal + force | 예 | 아니요 | 미확정 값의 undo |
| no-steal + no-force | 아니요 | 예 | 확정 값의 redo |
| steal + no-force | 예 | 예 | undo와 redo 모두 |
위 잔액 예제의 목표 값 7을 두 장애 상태에 적용해 봅니다.
- T1의
10→7로그와 커밋 기록은 영구 저장됐지만 no-force여서 데이터 페이지는 아직 10입니다. 확정 로그를 따라10→7을 다시 반영하는 redo가 필요합니다. - T1 뒤 T2의
7→5로그가 저장되고 steal로 미커밋 페이지 5까지 내려간 뒤 장애가 났습니다. T2는 커밋하지 않았으므로 설명용 값 로그의 이전 값 7로 되돌리는 undo가 필요합니다.
두 상태의 데이터 파일은 각각 10·5로 다르지만 복원할 확정 사실은 같은 7입니다. 이 순차·단일 값 추적을 모든 동시 트랜잭션의 회복 알고리즘으로 일반화하지 않습니다. WAL은 로그를 먼저 저장하는 순서이고 steal/force는 데이터 페이지를 언제 저장할지의 정책이므로 서로 다른 질문입니다. 회복 정책과 WAL 강의 노트는 페이지 정책의 원자성·내구성 문제와 로그 규칙을 이어 설명합니다.
체크포인트는 회복을 시작할 로그 위치와 관련 상태를 관리해 재시작 작업을 줄입니다. 모든 트랜잭션이 끝났거나 모든 undo가 필요 없어졌다는 뜻은 아닙니다. 그림자 페이지 방식은 이전 페이지와 새 페이지를 분리하고 완료 시 참조를 전환하는 대안입니다. 페이지·참조의 쓰기 순서와 원자성 조건이 필요하며 InnoDB가 이 방식으로 구현됐다고 설명하지 않습니다.
InnoDB에서 연결해 보기
InnoDB는 redo로 변경을 회복하고 미완료 트랜잭션을 롤백합니다. undo는 롤백뿐 아니라 과거 행 버전을 읽는 MVCC에도 사용됩니다. redo, undo, binary log는 이름만 다른 한 로그가 아닙니다. binary log는 복제와 시점 복구에 쓰이는 서버 계층의 기록입니다. InnoDB 회복, 다중 버전과 undo
CREATE DATABASE IF NOT EXISTS cs_db_lab;
USE cs_db_lab;
SELECT VERSION(),@@innodb_flush_log_at_trx_commit,@@sync_binlog;
DROP TABLE IF EXISTS cs_recovery_account;
CREATE TABLE cs_recovery_account(id INT PRIMARY KEY,balance INT NOT NULL) ENGINE=InnoDB;
INSERT INTO cs_recovery_account VALUES(1,100);
START TRANSACTION;
UPDATE cs_recovery_account SET balance=70 WHERE id=1;
SELECT balance FROM cs_recovery_account WHERE id=1;
ROLLBACK;
SELECT balance FROM cs_recovery_account WHERE id=1;
START TRANSACTION;
UPDATE cs_recovery_account SET balance=90 WHERE id=1;
COMMIT;
SELECT balance FROM cs_recovery_account WHERE id=1;같은 연결의 결과는 차례로 70,100,90입니다. 이 실습이 검증하는 것은 자기 변경·ROLLBACK·COMMIT의 결과입니다. 장애 후 재시작, 저장 장치 내구성, 백업 복원을 검증한 결과는 아닙니다. 설정값을 기록하되 학습 때문에 운영 서버의 내구성 설정을 낮추지 않습니다.
백업과 복구의 경계
로그가 남아 있어도 같은 장치의 데이터와 로그를 모두 잃으면 충분한 복구 재료가 없을 수 있습니다. 백업은 별도 복원 가능한 사본이고, 복구 목표 시점까지 가려면 적합한 후속 로그와 일관된 기준점도 필요합니다. 사본 파일의 존재보다 별도 환경에서 실제 복원하고 무결성을 확인한 증거가 중요합니다. 오류를 복제한 복제본도 과거 정상 시점의 백업을 자동 대체하지 않습니다.
장애 시점의 값과 확정 값을 구분한다
첫 변경이 커밋된다. 확정된 변경만 반영한다. 각 단계의 값과 전환 이유를 비교합니다.
장애 시점의 값과 확정 값을 구분한다
초기 10에서 T1이 7로 커밋하고 T2가 5로 바꿨지만 미커밋 상태에서 장애가 발생한 추상 모델입니다.
이 예의 조건
- 본문과 전체 도표의 예를 따라 T1 완료부터 복구 목표까지 진행합니다.
관계도의 보충 설명
| 구분 | 전체 도표의 내용 |
|---|---|
| 관계 설명 | 초기 10에서 T1이 7로 커밋하고 T2가 5로 바꿨지만 미커밋 상태에서 장애가 발생한 추상 모델입니다. T1 완료: 10 → 7 커밋; T2 미완료: 7 → 5 후 장애; 확정 상태 복원: 목표 값: 7. 화살표는 설명용 사건 순서이며 실제 시간 간격이나 InnoDB 로그 형식이 아닙니다. 페이지 정책에 따라 redo/undo의 적용 근거를 확인합니다. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| T1 완료 첫 변경이 커밋된다. |
|
|
| T2 중 장애 다음 변경은 아직 확정되지 않았다. |
|
|
| 복구 목표 확정된 변경만 반영한다. |
|
|
장애 시점의 값과 확정 값을 구분한다
첫 변경이 커밋된다. 확정된 변경만 반영한다. 각 단계의 값과 전환 이유를 비교합니다.
장애 시점의 값과 확정 값을 구분한다
초기 10에서 T1이 7로 커밋하고 T2가 5로 바꿨지만 미커밋 상태에서 장애가 발생한 추상 모델입니다.
이 예의 조건
- 본문과 전체 도표의 예를 따라 T1 완료부터 복구 목표까지 진행합니다.
관계도의 보충 설명
| 구분 | 전체 도표의 내용 |
|---|---|
| 관계 설명 | 초기 10에서 T1이 7로 커밋하고 T2가 5로 바꿨지만 미커밋 상태에서 장애가 발생한 추상 모델입니다. T1 완료: 10 → 7 커밋; T2 미완료: 7 → 5 후 장애; 확정 상태 복원: 목표 값: 7. 화살표는 설명용 사건 순서이며 실제 시간 간격이나 InnoDB 로그 형식이 아닙니다. 페이지 정책에 따라 redo/undo의 적용 근거를 확인합니다. |
| 관찰·상황 | 값·보충 정보 | 변화·이유 |
|---|---|---|
| T1 완료 첫 변경이 커밋된다. |
|
|
| T2 중 장애 다음 변경은 아직 확정되지 않았다. |
|
|
| 복구 목표 확정된 변경만 반영한다. |
|
|
연습과 오개념 확인
T1이 10→8로 커밋했고 T2가 8→6으로 바꾼 뒤 미커밋 상태로 장애가 났습니다. 추상 모델의 확정 잔액은 얼마인가요? 체크포인트 뒤에 시작한 T2가 있었다는 이유만으로 T2의 철회를 생략해도 될까요? ROLLBACK 실습 통과를 백업 복원 통과로 기록하면 왜 틀리나요? 추가로 no-steal + no-force 정책에서 T1의 로그·커밋은 영구 저장됐고 데이터 페이지가 아직 10이면 어떤 회복 방향이 필요한가요?
힌트
확정 여부, 저장 위치, 회복 재료를 각각 분리합니다.
풀이
확정 잔액은 8입니다. 체크포인트는 미완료 트랜잭션을 커밋시키지 않으므로 해당 회복 모델의 undo 조건을 확인해야 합니다. ROLLBACK은 살아 있는 서버에서 한 트랜잭션을 철회한 것이고, 백업 복원은 별도 사본으로 서버/데이터를 되살리는 작업이어서 검사 대상이 다릅니다. 마지막 경우에는 no-steal이라 T2의 미커밋 6은 데이터 파일에 내려가지 않지만 no-force라 확정 8도 아직 반영되지 않았습니다. 따라서 이 값 모형에서는 T1의 10→8을 redo해야 합니다.
회복은 커밋 상태·페이지 정책·로그 순서를 연결하는 문제입니다. 다음 본문은 누가 이러한 데이터에 접근할 수 있는지 계정과 역할로 제한합니다.