[18장] 크래시 리커버리

임정환·2023년 6월 12일
0

응용데이터베이스

목록 보기
4/9

만일 TX의 진행 도중 예상치 않게 Crash가 발생했다면 ( 컴퓨터가 꺼진다던지) 어떻게 해야할까?
DBMS의 Recovery Manager 컴포넌트가 log를 통해 crash를 복구해 줄 것이다.

ACID

DBMS의 보장 사항

  • Atomicity : TX의 모든 action은 일어나거나 안일어나거나. 즉, 절반만 한다던지는 있을 수 없다.
  • Cosistency : 일관성을 보장해야한다
  • Isolation : 각 TX의 실행은, 다른 TX의 영향을 받지 않는다.
  • Durability : TX이 커밋됬다면, 이는 Disk에 영구적으로 반영되어야 한다

Recovery Manager의 목표는 Atomicity와 Durability를 보장한다.
반면에, Buffer Manager의 목표는 response time의 최소화와 throughput의 최대화이다. 두 Manager간의 목표가 상충되는 부분이 존재하므로 , 이를 어떻게 해결하는지 알아보자

Motivation

  • Atomicity : 만일 TX이 abort되어서 롤백되었다면?
  • Duraibility : 만일 DBMS가 비정상 종료되었다면


인터리빙한 TX들이 진행중 Crash가 발생한 상황

  • T4와 T5의 TX 진행중 crash 발생
    • T1,T2,T3는 Disk에 영속적으로 저장되어야한다 (즉, 아직 write된 데이터가 버퍼에 남아있다든지의 이유로 Disk에 반영이 안되어있으면 안된다)
    • T4,T5는 undo되어야 한다 (TX은 atomic해야하므로 , 진행중 Crash 되었다면 Undo되어야 한다)
    • 리커버리 매니저가 log를 통해 해당 작업을 수행한다

버퍼풀 관리

TX 처리 시 , 데이터 기록에 관한 옵션

  • Force
    • TX 완료 후 , 데이터를 바로 디스크에 저장
    • Response time이 감소한다.
    • Durability를 제공한다.
  • Steal
    • TX이 Commit되지 않은 상황에서 , Frame을 교체한다.
    • TX이 진행중인데 참조하는 frame이 교체 정책에 의해서 교체된 경우
    • throughput이 증가한다.
    • Atomicity를 제공하기 어렵다.

No Force , Steal -> 버퍼매니저가 원함 ( 처리율 증가 및 반응 시간 감소 )
Force , No Steal -> 리커버리매니저가 원함 ( Atomicity 및 Durability 보장 )
기본적으로 DBMS는 No Force , Steal 을 따르므로 리커버리 매니저가 Atomicity와 Durability를 보장할 수 있는 방법을 찾아야한다.

Force/Steal Detail

  • Steal ( 왜 Atomicity를 보장하기 힘들까?)
    • 작업중인 TX이 lock을 소유하고 있는 Frame이 Disk에 쓰였다.
      • 만약, Frame에 대한 lock을 소유하고 있는 TX이 abort되면?
      • UNDO를 통해 해결한다
  • No Force ( 왜 Durability를 보장하기 힘들까?)
    • 만일 , 변경된 Frame이 Disk에 쓰이기 전 ( 즉, buffer pool에만 존재)에 system에 장애가 발생한다면?
    • REDO를 통해 해결한다

기본적 아이디어 : 로그

리커버리 매니저가 변경 전,후의 데이터를 logging 한다.
로그는 REDO/UNDO action들의 순서 list이다.

위와 같이 Log record의 list의 저장을 통해 Redo/Undo가 가능하다.

Write Ahead Log Protocol

WAL 프로토콜
데이터의 변경 전, Log를 선행하여 기입

  • 연관된 data page가 disk에 기록되기 전, 반드시 log 레코드를 업데이트
    • Atomicity 보장
  • TX의 commit 전, log를 기록
    • Durability 보장

WAL 상세

  • 각 log 레코드는 유니크한 log sequence number (LSN) 을 소유한다.
  • Crash Recovery를 위해 , 데이터 베이스에 존재하는 각 페이지는 해당 페이지의 가장 최근에 일어난 변경을 기술하는 LSN을 소유한다. 해당 LSN을 page LSN(Datablock에 반영된 가장 마지막 로그 번호)이라고 한다.
  • System은 flushedLSN( disk에 반영된 가장 최근 LSN)을 가지고 있다.

로그 레코드 구조 및 로그 테이블

  • 로그레코드의 필드

    • prevLSN : 현재 log 이전의 가장 최근 log를 포인팅
    • XID : TX의 id
    • type : 일어난 action의 종류를 기입

    그 외 여러 필드를 소유한다.

  • 로그 레코드의 타입

    • Update
    • Commit
    • Abort
    • End ( commit이나 abort의 종료를 나타냄 )
    • Compensation Log Records ( CLRs )
      • UNDO action을 위해 존재

  • TX Table
    • 진행중인 TX을 entry로 소유
    • XID와 Status ( running / commited / aborted) 그리고 lastLSN( TX안에서 일어나는 여러가지 read/write 중 가장 마지막에 일어난 action에 대한 log 번호) 포함
  • Dirty Page Table
    • buffer pool에 존재하는 dirty page를 entry로 소유
    • recLSN을 소유
      • recLSN은 해당 페이지를 가장 최근에 write한 최신 로그의 번호

TX의 실행

TX 실행 시 일어나는 일련의 작업

  • 일련의 read와 write , 이후로 commit과 abort로 마무리
  • Strict 2PL
  • Steal , No Force 버퍼관리
  • Write Ahead Log 기법 사용
    • TX이 일어나기 전 , 로그를 미리 기록 ( redo 와 undo를 위해 )

체크포인팅

System의 장애로부터 recovery time을 최소화하기위해 주기적으로 DBMS는 체크포인트를 생성한다.

  • Begin_checkpoint 레코드
    체크포인트의 시작점(begin_checkpoint 레코드)을 기록하고 로그에 포함한다.
  • End_checkpoint 레코드 ( fuzzy checkpoint )
    begin_checkpoint당시의 TX table과 dirty page table을 End_checkpoint에 기록하고 로그에 포함한다.
  • 체크포인트 레코드의 LSN을 safe place에 보관한다. (master record)

시스템의 장애 발생 이후,

저장되는 자료구조 정리

간단한 TX Abort 알고리즘

TX abort에 대해 알아보자 , Crash 발생 없이 abort를 한다고 가정한다.
Update를 undo하고 log를 통해 'play back'하고 싶다.

  • TX table의 TX들의 lastLSN 번호를 알아낸다.
  • 레코드의 'prevLSN' 필드를 통해서 , Chain 방식으로 로그 레코드들을 찾아나갈 수 있다.
  • Undo 시작 전 , Abort log record를 기록한다.
    • Undo 중 crash가 일어났을 경우를 대비하기위해!
  • Undo 시작 전, data에 대한 lock을 걸어야한다.
  • Page에 예전 값을 write 하기 전에 CLR을 작성한다.
    • Undo중 fail 시에 , CLR을 통해 어디서부터 다시 Undo할지 결정가능
    • CLR에는 undonextLSN이라는 필드가 존재한다.
      • 다음으로 undo해야할 LSN을 포인팅한다.
  • Undo의 마지막에 end log 레코드를 작성한다.

TX Commit 알고리즘

  • log에 commit을 작성한다.
  • TX의 lastLSN까지 Disk에 flush된다.
    • 이로서 flushedLSN이 lastLSN임을 보장한다.
  • Commit()을 반환한다.
  • end 레코드를 log에 기록한다.

크래시 리커버리 개요

장애 복구상황의 개요를 살펴보자
우선 장애발생시 master record로부터 체크 포인트를 찾는다. 그 후, crash recovery가 시작된다.

  • Last 체크포인트로부터 Crash가 발생한 지점을 Analysis
  • history를 참조하여 모든 action을 redo한다 ( Commit TX들에 대해서 )
  • fail한 TX에 대하여 Undo를 진행한다 ( abort TX들에 대해서 )

크래시 리커버리 순서도

Analysis 단계

  • Checkpoint를 통해서 State를 재구성한다.
    • END_CHECKPOINT 레코드를 이용한다.
  • 체크포인트부터 크래시 시점까지의 로그들을 스캔한다.
    • END타입 로그 레코드
      • 해당 TX을 TX table에서 삭제. TX이 end로 끝났기 때문에 active하지 않기 때문이다.
    • 다른 타입 로그 레코드
      • TX을 TX table에 추가해준다.
      • 해당 TX의 lastLSN을 현재 로그 레코드의 LSN으로 설정한다.
        • 만일 로그 레코드 타입이 commit이라면 TX 엔트리의 state를 commit으로 설정한다.
    • 페이지 P에 대한 UPDATE 레코드
      • 만약 해당 Page가 Dirty Page Table에 없을경우
        • 만약 DPT에 해당 페이지가 없다면 추가
        • recLSN = LSN 으로 세팅

Redo 단계

  • repeat history를 통해 Crash 당시의 State 재구성
    • 모든 Update를 재적용 ( abort된 TX 까지 ) , CLR들을 Redo
  • Dirty Page Table 안에서 가장 작은 recLSN을 포함하고 있는 Log 레코드를 찾는다( 가장 오래된 dirty page). 각 CLR 혹은 update log의 recLSN에 대하여 다음 케이스가 되기 전까지 반복적으로 REDO를 한다.
    • Crash의 영향을 받은 page가 더이상 Dirty Page Table에 없는 상태
    • Crash의 영향을 받은 page가 Dirty Page Table에 존재하지만 , 해당 페이지의 recLSN > LSN 이거나 pageLSN>LSN 인 상태
  • Redo action
    • log된 action을 재적용한다
    • pageLSN을 적용한 action의 log로 세팅한다. 추가적인 log를 기록하지 않는다.

Undo 단계

ToUndo 집합이 공집합이 될 때까지 다음을 반복한다.

  • ToUndo 집합에서 가장 큰 LSN을 찾는다.
  • 만약 해당 LSN이 CLR이고 undonenextLSN == NULL 이라면
    • 해당 TX에 End 레코드를 작성한다.
  • 만약 해당 LSN이 CLR이고 undonenextLSN != NULL 이면
    • undonenextLSN을 ToUndo에 추가한다.
  • 만약 해당 LSN이 Update일 경우.
    • Update를 Undo한다.
    • CLR을 작성한다.
    • prevLSN을 ToUndo에 추가한다.

크래시 리커버리 예제


profile
CS 박제

0개의 댓글