[데이터베이스] 회복

백업(Backup)현재의 데이터베이스를 다른 매체에 보관하는 작업을 말한다. 

회복(Recovery)은 데이터베이스에 문제 발생 시에 다른 매체에 백업된 데이터를 이용해서 원상태로 돌려놓는 작업을 말한다. 

 

회복과 관련된 데이터 저장장치로 다양한 종류가 존재할 수 있는데, 이들은 고장에 대한 회복력에 따라 휘발성, 비휘발성, 안정 저장장치로 구분해 볼 수 있다. 

  • 휘발성 저장장치(Volatile storage) : 메인 메모리와 같이 시스템 고장 시에 저장된 정보가 유실된다.
  • 비휘발성 저장장치(Nonvolatile storage) : 디스크나 자기 테이프와 같이 시스템 고장 시에도 일반적으로 저장된 정보는 손실되지 않는다. DB 시스템에서는 디스크가 가장 많이 사용되고, 자기 테이프는 백업용으로 사용된다. 
  • 안정 저장장치(Stable storage) : 서로 다른 디스크에 각 블록의 사본을 저장하는 RAID(Redendant Array of Inexpensive) 시스템이 될 수 있다. 

📄 데이터베이스 입출력 연산

데이터베이스의 장애와 회복을 이해하기 위해서는 먼저 데이터베이스 연산이 데이터 저장장치와 어떠한 관계를 맺고 있는지 알아야 한다. 데이터베이스는 실제로 비휘발성 저장장치(보통 디스크)에 영구 저장되기 때문에 트랜잭션디스크로부터 메인 메모리로 데이터를 입력시키고 다시 디스크로 정보를 출력한다. 이때 입출력 연산블록 단위로 이루어진다. 디스크에 있는 블록물리적 블록(physical block)이라 하며, 메인 메모리에 임시 거주하는 블록버퍼 블록(buffer block)이라 한다.

 

디스크와 메인 메모리 사이의 블록 이동은 다음 두 가지 연산에 의해 수행된다.  

  • $Input(B_i)$
    • 물리적 블록 $B_i$를 메인 메모리로 전송
    • 사용자의 요청에 의해(on demand) 수행
  • $Output(B_i)$
    • 버퍼 블록 $B_i$를 디스크로 전송해 적절한 물리 블록으로 대치
    • 버퍼 관리자(by buffer manager)에 의해 수행


📄 장애

회복이란, 장애가 일어났을 때 데이터베이스를 장애가 발생했던 이전의 상태로 복구시켜서 일관된 상태(Consistent state)를 만드는 것을 말한다. 여기서 일관된 상태란, 데이터베이스 내에 오류나 모순이 없는 상태를 말한다. 

장애(Failure)란, 시스템의 내부적 문제, 외부적 문제로 인해 정해진 명세대로 작동하지 않는 상태를 말한다. 이와 같은 문제로 발생되는 장애는 다음과 같이 크게 세 가지 유형으로 구분할 수 있다. 

  • 트랜잭션 장애 : 트랜잭션 내의 논리적 오류(e.g. devided by 0), 입력 데이터의 불량, 데이터를 찾을 수 없는 경우 등으로 정상적인 실행이 불가능한 상태
  • 시스템 장애 : 교착 상태와 같이 예기치 못한 상황이 발생하여 더 이상 정상적인 작업을 수행할 수 없는 상태나 하드웨어 오작동으로 인해 메인 메모리에 저장된 데이터가 손실되어 더 이상의 실행을 진행할 수 없는 상태
  • 미디어 장애 : 디스크의 고장으로 저장장치의 데이터베이스 일부 또는 전부가 손상된 상태

📄 회복의 개념

데이터베이스 회복의 기본 원리데이터의 중복(Redundancy) 저장이다. 작업 도중 발생하는 정보를 한 곳에만 저장하는 것이 아니라 별도로 어디엔가 중복해서 저장해 두었다가 장애가 발생했을 때 이 정보를 이용해 다시 복원시키는 것이다. 

이러한 중복 저장을 만드는 기법으로 덤프로그가 있다. 

  • 덤프(Dump) : 데이터베이스의 모든 내용일정한 주기다른 저장장치에 복제(archive)하는 것
  • 로그(Log) : 데이터베이스가 변경될 때마다 변경되는 데이터 값의 이전 값(old value)과 이후 값(new value)별도의 로그 파일에 저장하는 것

📄 회복 조치의 유형

장애가 발생했을 때 회복을 위해 취할 수 있는 조치는 일반적으로 다음 두 가지 유형이 있다. 

🏷 REDO(재수행)

데이터베이스 내용 자체가 손상된 경우에 사용한다. 복사본과 로그 파일을 이용해 데이터베이스를 복구하는 것을 말한다. 

죽, 가장 최근에 덤프 받은 복사본을 적재시킨 뒤, 이 복사본 이후에 일어난 변경로그를 이용해 재수행함으로써 최근의 상태로 데이터베이스를 복원하는 것이다.

🏷 UNDO(취소)

데이터베이스 내용 자체는 손상되지 않았지만, 변경 중이었거나 변경된 내용에 대한 신뢰성을 잃어버린 경우에 사용한다. 

로그 파일을 이용모든 변경된 사항들을 취소시킴으로써 데이터베이스를 원래의 상태로 복원시키는 것이다.


📄 데이터베이스 로그를 이용한 회복

데이터의 변경이 발생할 때마다 생성되는 로그 파일을 이용하는 것이다. 변경한 내용을 언제 반영하느냐에 따라 즉시 갱신 회복 기법지연 갱신 회복 기법으로 분류할 수 있다. 

먼저 로그를 구성하는 레코드를 살펴보면, 각 로그 레코드를 구별하기 위한 트랜잭션 ID가 포함되고, 트랜잭션 ID가 생성될 때마다 해당 ID에 속하는 이전 값(old value)과 이후 값(new value)에 대한 정보도 존재한다. 이러한 로그 레코드들은 다음과 같은 유형으로 구분할 수 있다. 

  • $<T_i, Start>$ : 하나의 트랜잭션 $T_i$가 시작될 때 기록되는 로그 레코드
  • $<T_i, X, V_1, V_2>$ : 트랜잭션 $T_i$의 데이터 항목 X를 이전 값 $V_1$에서 이후 값 $V_2$로 변경되었음을 나타내는 로그 레코드
  • $<T_i, commit>$ : 트랜잭션 $T_i$가 모든 갱신을 성공적으로 완료하였음을 나타내는 로그 레코드
  • $<T_i, abort>$ : 트랜잭션 $T_i$가 철회되었음을 나타내는 레코드. 해당 트랜잭션의 모든 변경 사항을 취소한다. 

🏷 즉시 갱신(Immediate update) 회복 기법

로그를 기반으로 한 즉시 갱신 회복 기법은 트랜잭션 연산 도중에 데이터 변경 연산이 발생될 때마다 데이터 변경 결과를 즉시 데이터베이스에 반영하는 것이다. 로그 파일에도 변경 내용을 함께 저장한다.

만약 트랜잭션 수행 도중 실패 상태가 발생하여 철회하게 되면 로그 파일에 저장된 내용을 참조하여 UNDO 연산을 수행한다. 이때 트랜잭션이 실행되기 전 상태의 데이터 값으로 복원시켜야 하므로 로그 레코드 값 중에서 이전 값(old value)이 사용된다. 

로그가 데이터베이스 회복에 사용될 수 있기 위해서는 로그 레코드가 기록되기 전에 데이터베이스가 갱신되어서는 안 된다. 

 

이를 간단한 예시를 통해 알아보자. 은행 시스템에서 트랜잭션 $T_1$는 A 계좌에서 B 계좌로 50원을 송금하는 트랜잭션이라 하자. 이 트랜잭션은 다음과 같이 정의될 수 있다. 

$T_1$ :

read(A)

A = A - 50

write(A)

read(B)

B = B + 50

write(B)

트랜잭션 $T_2$는 C 계좌로부터 100원을 인출하는 트랜잭션이다. 

$T_2$ :

read(C)

C = C - 100

write(C)

이상의 트랜잭션이 $T_1$, $T_2$ 순서로 실행되고 A, B, C 계좌에는 실행 이전에 각각 1000원, 2000원, 700원이 예금되어 있다고 가정하자. 이 두 트랜잭션에 대한 로그는 다음과 같이 될 것이다. 

$$<T_1, Start>$$ $$<T_1, A, 1000, 950>$$ $$<T_1, B, 2000, 2050>$$ $$<T_1, commit>$$ $$<T_2, Start>$$ $$<T_2, C, 700, 600>$$ $$<T_2, commit>$$

만약 장애가 발생하면 회복 기법은 로그를 참조해 트랜잭션들이 REDO 되어야 하는지 UNDO 되어야 하는지를 결정한다. 이러한 트랜잭션 구분을 아래와 같이 이루어진다. 

  1. 로그에 $<T_i, Start>$ 레코드는 포함하고 있지만 $<T_i, commit>$ 레코드를 포함하지 않을 경우에는 트랜잭션 $T_i$는 UNDO되어야 한다. 
  2. 로그에 $<T_i, Start>$ 레코드와 $<T_i, commit>$ 레코드를 모두 포함하는 경우에는 트랜잭션 $T_i$는 REDO되어야 한다.

예시를 통해 살펴보면, 트랜잭션 $T_1$이 Commit 하기 직전에 시스템이 붕괴되었다고 하면 $<T_1, commit>$ 레코드가 로그에 없다. 따라서 UNDO($T_1$)을 실행해야 한다. 이 UNDO 연산을 실행한 뒤에 디스크에 있는 A와 B 계좌에는 각각 원래의 1000원과 2000원으로 되돌아가게 된다. 

일반적으로 회복 작업의 절차는 먼저 모든 UNDO 연산을 마친 뒤에 REDO 연산을 실행해야 한다.
UNDO 연산은 로그에 기록된 순서의 역순으로 수행하고
REDO 연산은 로그에 기록된 순서로 수행한다. 

🏷 지연 갱신(Deferred update) 회복 기법

트랜잭션이 부분 완료될 때까지 모든 변경 내용을 로그 파일에만 저장하고 데이터베이스에 저장하는 것지연한다. 부분 완료 상태에 이르면 로그 파일에 저장된 변경 내용을 참조하여 데이터베이스에 변경 내용을 반영한다. 만약 트랜잭션 실행이 완료되기 전에 장애가 발생하면 로그에 있는 정보는 그냥 버리고 무시한다. 즉, 부분 완료 이전까지 데이터베이스는 변경되지 않기 때문에 UNDO 연산은 실행할 필요가 없다. 

지연 갱신 회복 기법은 REDO 연산에 대비해 새로 변경된 데이터 값만 있으면 되기 때문에 로그 레코드에는 이전 값 필드가 없어도 된다. 즉, 로그 레코드는 <트랜잭션 ID, 데이터 항목, 변경된 값>의 형식을 갖는다. 

 

위의 은행 시스템의 예를 다시 고려해보면 다음과 같다. 

$$<T_1, Start>$$ $$<T_1, A, 950>$$ $$<T_1, B, 2050>$$ $$<T_1, commit>$$ $$<T_2, Start>$$ $$<T_2, C, 600>$$ $$<T_2, commit>$$

장애 발생 시 회복 방법은 다음과 같다. 

  1. 로그에 $<T_i, Start>$ 레코드는 포함하고 있지만 $<T_i, commit>$ 레코드를 포함하지 않을 경우에는 데이터베이스에 저장된 내용이 없기 때문에 로그 레코드를 폐기 또는 무시한다. 
  2. 로그에 $<T_i, Start>$ 레코드와 $<T_i, commit>$ 레코드를 모두 포함하는 경우에는 트랜잭션 $T_i$는 REDO 연산을 실행하여 로그 값들로 데이터베이스를 갱신한다. 

📄 검사 시점 회복

REDO, UNDO 되어야 할 트랜잭션을 결정하기 위해서는 원칙적으로 로그 전체를 분석해야 한다. 하지만 이는 시간이 너무 많이 걸리게 될 뿐만 아니라 할 필요가 없는 REDO 연산을 반복적으로 해야 되는 문제가 발생한다. 이러한 문제를 해결하기 위한 방법이 검사 시점(Checkpoint) 방법이다. 이 방법은 트랜잭션을 수행하는 동안 일정 간격으로 검사 시점을 만들어 놓는다. 이러한 검사 시점이 설정되면 해당 검사 시점 이전의 트랜잭션에 대해서는 회복 작업이 필요 없게 된다

즉, 장애가 발생했다 다시 시스템이 작동되면 회복 관리자는 로그에 있는 가장 최근의 해당 검사 시점을 찾아 그 시점 이후의 로그만을 회복 대상으로 하면 된다. 

 

아래 그림은 검사 시점 회복 방법에 있을 수 있는 5가지 트랜잭션 유형을 보여준다.

  • $T_1$은 검사 시점 c 이전에 실행을 완료하였으므로 회복 작업을 할 필요가 없다. 
  • $T_2$는 검사 시점 c 이전에 시작해 장애 시점 f 이전에 완료하였으므로 검사 시점 c 이후에 발생한 변경 부분에 대해서만 REDO 연산을 수행해야 한다. 
  • $T_3$는 검사 시점 c 이후에 시작하여 장애 시점 f 이전에 완료하였으므로 트랜잭션 전체에 대해 REDO 연산을 수행해야 한다. 
  • $T_4$는 검사 시점 c 이전에 시작했으나 장애 시점 f까지 트랜잭션이 미완료 되었으므로 트랜잭션 전체에 대해 UNDO 연산을 수행해야 된다. 특히, $T_4$는 검사 시점 c 이전에 수행했던 변경 부분도 UNDO 연산에 포함시켜야 된다
  • $T_5$는 검사 시점 c 이후에 시작하여 장애 시점 f까지 트랜잭션이 미완료 되었으므로 트랜잭션 전체에 대해 UNDO 연산을 수행하면 된다. 

📄 미디어 회복 기법

지금까지는 시스템 장애로 인해 휘발성 저장장치의 정보는 손실되지만, 비휘발성 저장장치의 내용은 손상되지 않는다는 가정 하에 회복 기법을 설명했다. 그러나 비휘발성 저장장치의 내용이 손상되는 경우가 드물긴 하지만 이런 유형의 장애에 대해서도 대비해 둘 필요가 있다. 

 

미디어 회복(Media recovery)의 기본 개념은 트랜잭션의 실행이 없을 때 데이터베이스의 전체 내용안정 저장장치에 주기적으로 덤프 처리를 실행하는 것이다. 따라서 미디어 장애가 발생하면 가장 최근의 덤프 정보를 이용해 장애가 발생되기 이전으로 복구한 후, 이것이 끝나면 로그를 이용하여 가장 최근의 일관된 상태로 데이터베이스를 복원시킨다.