데이터베이스 시스템은 원자성(Atomicity)과 지속성(Durability)을 보장하기 위해, 다양한 장애(Failure) 발생 시 데이터를 일관된 상태로 복구해야 합니다1.
트랜잭션 장애: 논리적 오류(내부 조건 불충족) , 시스템 오류(데드락 등)
System Crash: 전원 차단 하드웨어 고장 등으로 발생, 비휘발성 저장 장치(Disk)는 손상되지 않는다고 가정 (" Fail-stop assumption ")
디스크 장애: 헤드 충돌 등으로 저장 장치 자체가 손상되는 경우
회복 기법을 이해하기 위해서는 데이터가 저장되고 이동하는 방식을 알아야 합니다.
초기 데이터베이스 관리자(DBA)가 DB 설정 파일에서 버퍼 풀의 크기(예: 10GB)를 지정. DBMS 프로세스가 시작될 때, 이 크기만큼의 대규모 메모리 블록을 OS에 요청.
OS는 요청받은 크기만큼의 가상 메모리(Virtual Memory) 공간을 해당 DBMS 프로세스에게 할당
DB는 OS로부터 메모리 공간을 할당받은 DBMS는 이 공간을 버퍼 풀(Buffer Pool)로 지정하고 내부적으로 관리한다.
휘발성(Volatile): 주기억장치 (RAM) 등, 충돌 시 데이터 손실 , 전원 꺼질시 데이터 없어짐
비휘발성(Non-volatile): 디스크, 플래시 메모리 등, 충돌 시 생존하나 디스크 장애 시 손실 가능
이렇다고 해서 데이터가 영원히 안전한게 아님
안정 저장 장치(Stable Storage): 결코 손실되지 않는다고 가정되는 이상적인 저장소로, 데이터를 여러 디스크에 복제(RAID 등)하여 구현
• 데이터 이동 연산

◦ `input(B)`: B 데이터가 담긴 물리적 블록 B+를 디스크에서 버퍼(메모리)로 이동.
◦ `output(B)`: 버퍼의 블록 B를 디스크로 이동 및 덮어쓰기
운영체제(OS) 관점: 운영체제는 페이지 캐시(Page Cache) 또는 버퍼 캐시(Buffer Cache)*라는 이름으로 디스크 버퍼를 관리하며, 파일 시스템 관련 입출력 요청을 처리.
데이터베이스(DB) 관점: 데이터베이스 관리 시스템(DBMS)은 자체적으로 버퍼 풀(Buffer Pool)이라는 별도의 버퍼 영역을 RAM에 할당하여, DB 테이블이나 인덱스 페이지와 같은 데이터 블록을 캐싱하여 사용.
데이터베이스 관리 시스템(DBMS)이 자체적으로 트랜잭션 또는 세션을 위한 개별(Private) 메모리 공간을 관리하고 할당한다
Private 메모리 공간은 다음과 같은 목적으로 DBMS에 의해 할당됩니다.
정렬 버퍼 (Sort Buffer): ORDER BY, GROUP BY 또는 인덱스 없이 실행되는 조인(Join)과 같이 데이터를 메모리에서 정렬해야 할 때 임시로 사용되는 공간입니다. 이 작업은 다른 세션과 공유할 필요 없이 해당 세션에서만 사용됩니다.
해시 영역 (Hash Area): 해시 조인(Hash Join)을 수행할 때 해시 테이블을 구축하는 데 사용되는 공간입니다.
세션/연결 컨텍스트: 해당 트랜잭션의 상태, 권한, 현재 사용 중인 변수 등 세션의 생명주기와 관련된 정보를 저장합니다.

◦ `read(X)` / `write(X)`: 변수 X를 트랜잭션의 로컬 작업 영역으로 읽어오거나 버퍼에 쓰는 작업.
◦ 모든 Transaction 본인의 Private Work-Area 를 가짐
디스크 버퍼를 지나는 것도 다 이유가 있다.
◦ 중요: write(X)가 실행되었다고 해서 즉시 디스크에 기록(output)되는 것은 아닙니다.
X1 값을 알기 위해서는 반드시 Read(X) 를 해야함
Write(Y) 는 바로 써도 되고 , 바로 안써도 됨 → ????
데이터의 출처: 이 참조하는 원본 데이터는 디스크 버퍼(Buffer Pool)에 있는 블록. 그리고 Work Area 는 사본을 갖는다
격리성 (Isolation): 트랜잭션 이 블록의 데이터를 가져와 에서 작업을 시작하는 것은 이 해당 시점의 데이터를 가지고 작업하며, 다른 트랜잭션의 간섭으로부터 격리되기 위함이다.
접근 권한: 트랜잭션은 버퍼 풀의 데이터 를 직접 조작하기보다는, Read(X) 과정을 통해 의 사본이나 참조를 과 연결하여 자신의 작업 공간에서 사용하게 된다. 따라서 의 내용을 기반으로 한 을 알기 위해서는 이 Read 과정이 필수적이다.
- Successful Completion : 완전 성공
- Partail Failure : 중간에 실패
- Total Failure : 시작에 실패
가장 널리 쓰이는 회복 기법으로, 모든 변경 사항을 안정 저장 장치(Log)에 먼저 기록한 후 데이터베이스에 반영합니다.
• 로그 레코드 구조: 트랜잭션이 커밋(Commit)되는 시점에 ,
형태로, 트랜잭션 ID, 데이터 항목,
- 변경 전 값(), 변경 후 값()
변경된 내용을 담은 리두 로그(Redo Log)를 먼저 안정 저장소 (Stable Storage) 에 즉시 기록.
트랜잭션이 커밋(Commit)되었는데, 해당 변경 내용이 아직 디스크의 데이터 파일에 반영되기 전에 충돌이 발생했을 경우 (즉, 변경 사항이 버퍼 풀에만 남아있는 경우), 복구 시 로그 파일을 확인하여 이 커밋된 내용을 데이터베이스에 다시 실행(REDO) 함으로써 영속성을 보장할 수 있다.
취소(Abort)되거나 충돌 시 미완료(Uncommitted) 상태였던 트랜잭션의 변경 사항이 혹시나 데이터베이스에 남아 있다면, 복구 시 로그 파일을 확인하여 이 변경 내용을 취소(UNDO)함으로써 데이터베이스를 충돌 이전 상태로 되돌리고 원자성을 보장할 수 있다.
트랜잭션이 데이터를 변경했을 때, 해당 변경 내용을 디스크 버퍼(Buffer)나 디스크(Disk)에 바로 반영하지 않고, 트랜잭션이 커밋(Commit)되는 시점에 일괄적으로 반영하는 방식.
복구의 일부 측면을 단순화: 이 방식은 트랜잭션이 커밋되기 전에 시스템이 충돌하면, 데이터베이스에 아무런 변경도 가해지지 않은 상태가 됩니다.
따라서 실패한 트랜잭션에 대해 UNDO 연산(변경 내용을 되돌리는 작업)이 필요 없습니다. 복구 시에는 REDO 연산(커밋된 트랜잭션의 변경 내용을 다시 적용하는 작업)만 수행하면 됩니다.
로컬 복사본 저장 오버헤드 : 변경된 데이터를 커밋 시점까지 별도의 로컬 임시 저장소(Private Area 또는 워크 에어리어)에 보관해야 하므로, 이로 인한 메모리 및 관리 오버헤드가 발생할 수 있습니다.
트랜잭션이 데이터를 변경하면, 그 변경 내용을 트랜잭션이 커밋되기 이전이라도 즉시 디스크 버퍼에 반영하는 방식.
로그는 Stable Storage 에 저장된다.
Commit Log 가 Stable Storage에 저장되어야 진정한 Commit 이 된 것. (Memory 수준에서의 Commit X)
동시성 제어(Concurrency Control)의 핵심인 2PL은 트랜잭션의 직렬성(Serializability)을 보장하며, 복구(Recovery) 과정은 원자성(Atomicity)과 영속성(Durability)을 보장합니다.
(Redo/Undo Phase)는 시스템 충돌 직후 데이터베이스의 일관된 상태(Consistent State)를 재구성하는 과정이다. 2PL은 트랜잭션 실행 중 데이터 접근을 제어하여 이 일관성을 유지하는 역할을 합니다.복구 과정에서 2PL 원칙의 영향은 주로 Undo Phase에서 명확하게 나타납니다.
<Ti, X, V1, V2> V1->V2 , X:=v1
2PL과의 관계: 이 단계는 복구가 주 목적이므로, 충돌 시점 이전에 적용되었던 잠금(Lock) 정보나 동시성 제어 규칙을 다시 적용하지 않는다.
단순히 로그에 기록된 모든 갱신() 을 순서대로 데이터베이스에 적용합니다.로그를 순방향으로 스캔하면서,
<T_i Commit>이나 <T_i Abort> 레코드를 발견하지 못한 트랜잭션들을 undo-list에 추가합니다.
이들은 충돌 시점에 완료되지 못한 트랜잭션.
미완료 트랜잭션()의 변경 사항을 취소하여 데이터베이스를 일관된 상태(충돌 이전의 커밋된 상태)로 되돌립니다.
2PL과의 관계: Undo Phase는 직접적으로 2PL을 수행하지는 않지만, Undo 작업 중에는 새로운 동시성 문제가 발생하지 않도록 보장해야 합니다.
<Ti, X, V1, V2> V1->V2 , X:=V2
-> 로그만 보고도 Undo 인지 Redo 인지 판단 그 시점에서 어떤 일이 일어났는지 알 수 있어야 함.
로그 종류
<T0 , Start> , <T1 , x, V1,v2> , <T1,X,V> - Read , <T1,commit> ,
<T1,abort> -> <T1 , Start> 수준으로 다시 돌아갔음을 의미
<T1,commit> 이 나왔으면 그 위로는 undo 를 할 필요가 없음
로그 전체를 검색하여 복구하는 것(Undo / Redo)은 시간이 너무 많이 소요되므로, 주기적으로 체크포인트를 수행하여 복구 시간을 단축할 수 있다.
• 수행 과정:
1. 체크포인트를 만드는 동안 모든 갱신(Update)을 잠시 중단.
2. 메모리에 있는 모든 로그와 버퍼 블록을 안정 저장 장치(디스크)로 출력 (output).
3. 현재 활성화된 트랜잭션 목록 을 포함한 로그 레코드 을 기록.
•
효과: 장애 발생 시, 가장 최근의 체크포인트 이후의 기록만 검사하면 되므로 회복 속도가 빨라집니다.