Post

Database - Recovery(ARIES)

Recovery - ARIES

1. 개요

ARIES(Algorithms for Recovery and Isolation Exploiting Semantics)는 DB 복구를 위해 나온 알고리즘이다.
모든 시스템이 이 논문에서 정의한 대로 ARIES를 정확히 구현하는 것은 아니지만 대부분 비슷하게 구현되어있으며 이를 알게 되면 복구에 대해서 이해할 수 있다.

2. 전제 조건

이 ARIES를 통해 Recovery를 구현하기 위해서는 아래와 같은 세가지 조건이 선행되어야한다.

1) 미리 쓰기 로깅

  • 데이터베이스 변경 사항이 디스크에 기록되기 전에 모든 변경 사항이 안정적인 스토리지의 로그에 기록된다.
  • STEAL + NO-FORCE 버퍼 풀 정책을 사용해야 한다.

2) 다시 실행 중 기록 반복:

  • DBMS 재시작 시 작업을 되돌리고 충돌 전 상태로 데이터베이스를 복원한다.

3) 실행 취소 중 변경 사항 로깅

  • 반복적인 실패 발생 시 작업이 반복되지 않도록 실행 취소 작업을 로그에 기록한다.

3. 세부 구현 내역

1) Log Sequence Numbers

원래 있던 WAL Record 방식에서 Recovery를 위한 추가정보가 있어야하기 때문에 레코드 형식이 확장되야한다.

모든 로그 레코드에는 전역적으로 고유 로그 시퀀스 넘버(LSN)이 포함된다. 여기서 LSN은 트랜잭션이 데이터베이스를 변경하는 물리적 순서를 나타낸다.

그외 다른 확장 정보는 아래와 같다.

NameWhereDefinition
flushedLSNRAM디스크에 로그 안에 있는 마지막 LSN
pageLSN@page i가장 최근 업데이트한 page로 Buffer pool에 있는 각 페이지마다 가진 값들이다
recLSN@page i가장 이전 업데이트한 page로 Buffer pool에 있는 각 페이지마다 가진 값들이다
lastLSNTj트랜잭션 j에 실행된 가장 최신 LSN
MasterRecordDisk최신 체크포인트의 LSN

각 데이터 페이지에는 pageLSN이 있으며 이는 해당 페이지에 대한 가장 최근 업데이트의 LSN을 말한다.
시스템은 flushedLSN을 추적하는데 이는 지금 까지 플러시된 최근 LSN을 말하며 DBMS가 페이지 x를 쓰기 전에 적어도 아래의 지점까지 로그를 플러시 해야한다.

→ pageLSNx ≤ flushedLSN

그림으로 그리면 아래와 같다.

img.png

2) Normal Execution

기본적으로 모든 트랜잭션은 읽기 혹은 쓰기를 한 뒤에 Commit 혹은 Abort 되며 아래 설명에서는 다음과 같은 가정을 두고 설명한다

  • 모든 로그 레코드는 단일 페이지에 들어간다.
  • 디스크 쓰기는 원자적이다.
  • 단일 버전 관리 튜플은 Strong Strict 2PL을 사용한다.
    “단일 버전 관리”는 각 튜플(또는 행)에 대해 항상 하나의 버전만 사용 가능함을 의미함
  • WAL을 사용한 STEAL + NO-FORCE 버퍼 관리

트랜잭션이 커밋되면 DBMS는 로그에 COMMIT 레코드를 기록하고 트랜잭션의 COMMIT 레코드까지의 모든 로그 레코드가 디스크에 플러시되도록 보장한다.

  • 로그 플러시는 디스크에 순차적이고 동기적으로 기록된다.
  • 로그 페이지당 여러 개의 로그 레코드가 기록된다.

커밋이 성공하면 특별한 트랜잭션 종료(TXN-END) 레코드를 로그에 기록하는데 이는 트랜잭션에 대한 새로운 로그 레코드가 더 이상 로그에 나타나지 않음을 나타내며 이는 즉시 플러시할 필요는 없다.

그림으로 보는게 좀 더 이해가 쉬울 것이다. 아래 그림은 Memory에 위치한 WAL의 flush 과정을 그린 것이다.

img_1.png

트랜잭션이 COMMIT되어 해당 부분을 Disk에 있는 Log file로 Flush하려고 한다.

img_2.png

해당 부분을 disk로 옮긴 후 flushedLSN의 값을 19로 세팅한다.

img_3.png

이후 Memory에 있는 WAL 파일을 비워도 되는데, 이후 들어오는 트랜잭션 완료(TXN-END)의 값까지 모두 DISK에 포함될 필요는 없다.

3) Abort Operations

Abort는 하나의 트랜잭션에만 적용되는 실행 취소 작업이다. 로그 레코드에 이를 위해서 prevLSN 필드가 있다. 이는 각 트랜잭션의 Log Record들을 연결 리스트 형태로 유지하여 해당 트랜잭션의 Record들을 쉽게 역추적할 수 있도록 하는 역할을 한다.
Abort시에는 트랜잭션의 변경 사항을 되돌리기 위해 Log Record를 prevLSN 체인을 따라 역방향으로 탐색하며 Undo 작업을 진행한다. 이 Undo 작업 역시 기록되는데 이를 Compensation Log Records (CLRs)라고하며 CLRs로 로그에 기록된다. CLRs는 일반 update Log Record의 모든 필드와 Undo 작업을 수행해야할 다음 LSN을 가리키는 undoNext 포인터를 포함한다.
이 CLRs는 앞에서 설명했듯 log에 포함은 되지만 따로 CLRs가 디스크에 flush 될때까지 기다리지는 않고 트랜잭션이 중단 되었음을 애플리케이션에 알린다.

아래는 ABORT 과정에서 WAL이 어떻게 변하는지에 대한 예시이다.

img_4.png

왼쪽의 lineNum은 설명을 위해서 임의로 추가한 열이다.

0 : 트랜잭션 1이 시작했다.
1 : 트랜잭션 1이 A를 20에서 90으로 변경했다.
3 : 트랜잭션 1이 Abort 되어 Undo를 해야한다.
5 : A가 90이 된걸 다시 20으로 변경하여 Type은 CLR로 지정한다, 이후 UndoNext는 처리한 LSN의 prevLSN으로 지정한다.
6 : 트랜잭션 Undo가 완료되었다.

※ 미비된 내용은 추가 업데이트 예정 및 검증 예정이다.

참고자료

  • 서강대학교 김영재 교수님 고급데이터 베이스 강의 자료
  • Avi Silberschatz, Henry F. Korth, S. Sudarshan, Database System Concepts(McGraw-Hill, March 2019)
This post is licensed under CC BY 4.0 by the author.