DB 시스템에서의 장애와 DBMS 제공 회복 기능 => 트랜잭션 관리의 원자성, 영속성 특성 보장

Jin Hur·2022년 5월 26일
0

데이터베이스

목록 보기
11/12

reference: "데이터베이스 개론" / 김연희 / 한빛아카데미

트랜잭션의 특성을 보장하고, DB를 모순이 없는 일관된 상태로 유지하기 위해 DBMS는 회복 기능을 제공한다. DB가 조직의 중요한 데이터를 저장하고 있는 만큼 DBMS의 회복 기능은 매우 중요한 기능이다.

회복은 장애가 발생했을 때 DB를 장애가 발생하기 전의 일관된 상태로 복구시키는 것이다.
DB 시스템에서 발생할 수 있는 장애의 유형과 회복 기능이 있다.


DB 시스템에서 발생하는 장애의 유형

시스템이 제대로 동작하지 않는 상태를 장애라고 한다. 장애가 발생하는 원인은 사용자의 실수, 정전 등으로 인한 HW 고장, SW의 논리적인 오류 등 매우 다양하다. DB 시스템에서 발생할 수 있는 장애는 크게 3가지 유형으로 분류할 수 있다.

  • 트랜잭션 장애
    (의미): 트랜작션 수행 중 오류가 발생하여 정상적으로 수행을 계속할 수 없는 상태
    (원인): 트랜잭션의 논리적 오류, 잘못된 데이터 입력, 시스템 자원의 과다 사용 요구, 처리 대상 데이터의 부재 등

  • 시스템 장애
    (의미): HW 결함으로 정상적으로 수행을 계속할 수 없는 상태
    (원인): HW 이상으로 메인 메모리에 저장된 정보가 손실되거나 교착 상태가 발생한 경우 등

  • 미디어 장애
    (의미): 디스크 장치 결함으로 디스크에 저장된 DB의 일부 혹은 전체가 손상된 상태
    (원인): 디스크 헤드의 손상이나 고장 등


DB의 저장 연산

DB는 기본적으로 저장 장치에 저장된다. 그리고 저장 장치는 장애가 발생했을 때 대응하는 방법에 따라 다음과 같이 세 종류로 분류할 수 있다.

  • 휘발성 저장 장치(소멸성): 장애가 발생하면 저장된 데이터가 손실됨. ex) 메인 메모리
  • 비휘발성 저장 장치(비소멸성): 장애가 발생하도 저장된 데이터가 손실되지 않음. 단 디스크 헤더 손상같은 저장 장치 자체에 이상이 발생하면 데이터가 손실될 수 있음. ex) 디스크, 자기 테이프, CD/DVD 등
  • 안정(stable) 저장 장치: 비휘발성 저장 장치를 이용해 여러 개 데이터 복사본을 만드는 방법으로, 어떤 장애가 발생해도 데이터가 손실되지 않고 데이터를 영구적으로 저장할 수 있음.

일반적으로 DB는 비휘발성 저장 장치인 디스크에 상주한다. 하지만 트랜잭션이 DB의 데이터를 처리하려면, 디스크에서 메인 메모리로 가져와 이를 처리한 후 그 결과를 다시 디스크로 보내는 작업이 필요하다.

source: https://velog.io/@bernard717/%EB%B3%B5%EA%B5%AC-%EC%8B%9C%EC%8A%A4%ED%85%9C

일반적으로 디스크와 메인 메모리 간의 데이터 이동은 블록(block) 단위로 수행된다(디스크 블록과 버퍼 블록).

  • input(X): 디스크 블록에 저장되어 있는 데이터 X를 메인 메모리 버퍼 블록으로 이동시키는 연산
  • output(X): 메인 메모리 버퍼 블록에 있는 데이터 X를 디스크 블록으로 이동시키는 연산

source: https://slidesplayer.org/slide/16478540/

사용자의 요구에 따라 응용 프로그램에서 트랜잭션의 수행을 지시하면 메인 메모리 버퍼 블록에 있는 데이터를 프로그램의 변수로 가져오고 데이터를 처리한 결과를 저장하고 있는 변수 값을 메인 메모리 버퍼 블록으로 옮기는 작업이 추가로 필요하다. 메인 메모리의 버퍼 블록과 프로그램 변수 간의 데이터 이동은 다음 두 연산으로 수행된다.

  • read(X): 메인 메모리 버퍼 블록에 저장되어 있는 데이터 X를 프로그램의 변수로 읽어오는 연산
  • write(X): 프로그램의 변수 값을 메인 메모리 버퍼 블록에 있는 데이터 X에 기록하는 연산

응용 프로그램에 의해 수행된 트랜잭션이 DB에 접근하여 처리할 데이터를 가져올 때 read(X) 연산이 실행된다. 그런데 read(X) 연산이 정상적으로 실행되려면 먼저 DB가 상주하고 있는 디스크에서 메인 메모리 버퍼 블록으로 데이터를 가져와야 한다. 그래서 내부적으로 input(X) 연산의 실행이 요구된다.
read(X) 연산이 실행되어 디스크에 존재하는 DB의 데이터가 프로그램 변수에 저장되면 해당 데이터에 대한 모든 연산은 프로그램 변수를 대상으로 처리된다. 트랜잭션이 성공적으로 완료되려면 트랜잭션의 모든 연산을 처리한 후 결과 값을 디스크의 DB에 반영해야 하는데, 이를 위해 write(X) 연산이 실행된 후 output(X) 연산이 실행된다.


회복 기법

=> 트랜잭션의 원자성과 지속성 보장

회복은 장애가 발생하였을 때 DB를 장애가 발생하기 전의 모순이 없고, 일관된 상태로 복구시키는 것으로, DBMS에 있는 '회복 관리자'가 담당한다. 회복 관리자는 장애 발생을 탐지하고, 장애가 탐지되면 DB를 복구하는 기능을 제공한다.
일반적으로 DB를 복구하는 동안에는 DB에 접근하여 업무를 처리할 수 없으므로, DB를 회복시키는 작업은 빠른 시간 내에 이루어져야 한다.

회복을 위한 연산

DB 회복의 핵심 원리는 데이터 중복이다. 데이터를 별도의 장소에 미리 복사해두고, 장애로 문제가 발생했을 때 복사본을 이용해 원래의 상태로 복원하는 것이다.
덤프 또는 로그 방법을 사용해 데이터를 복사해두었다가 회복시킬 때 복사본을 사용한다.

  • 덤프(dump): DB 전체를 다른 저장 장치에 주기적으로 복사하는 방법
  • 로그(log): DB에서 변경 연산이 실행될 때마다 데이터를 변경하기 이전 값과 변경한 이후의 값을 별도의 파일에 기록하는 방법

DB 전체를 복사하는 덤프 방법은 하루에 한 번 또는 한 달에 한 번과 같이 미리 정해진 주기에 따라 수행한다. 그리고 디스크와 같이 비휘발성 저장 장치에 DB 복사본을 저장한다.

장애가 발생했을 때 덤프나 로그 방법으로 중복 저장한 데이터를 이용해 취할 수 있는 가장 기본적인 회복 방법은 redoundo 연산을 실행하는 것이다.

  • redo(재실행): 가장 최근에 저장한 DB 복사본을 가져온 후 로그를 이용해 복사본이 만들어진 이후에 실행된 모든 변경 연산을 재실행하여 장애가 발생하기 직전의 DB 상태로 복구(전반적으로 손상된 경우에 주로 사용)

  • undo(취소): 로그를 이용해 지금까지 실행된 모든 변경 연산을 취소하여 DB를 원래의 상태로 복구(변경 중이였거나 이미 변경된 내용만 신뢰성을 잃은 경우에 주로 사용)

redo 연산과 undo 연산을 실행하는 데는 로그가 중요하게 사용된다. DBMS가 로그를 기록하는 방법을 좀 더 자세히 살펴볼 필요가 있다.

DBMS의 로그 기록

source: https://slidesplayer.org/slide/16478540/

로그는 DB에 대한 변경 연산과 관련하여, 데이터를 변경하기 이전의 값과 변경한 이후의 값을 기록한 것이다. 로그를 저장한 파일을 로그 파일이라고 하는데, 로그 파일은 레코드 단위(로그 레코드)로 기록된다. 일반적으로 로그 파일을 구성하는 레코드는 위 표와 같이 네 종류로 분류한다.
DB에 대한 변경 연산은 트랜잭션 단위로 실행되므로 로그 레코드로 트랜잭션의 수행과 함께 기록된다.
로그는 DB 회복 작업을 수행하기 위해 필요한 중요한 정보를 가지고 있으므로 데이터 손실이 발생하지 않는 저장 장치에 저장해둔다.

아래 그림은 계좌 잔액이 10,000원인 성호가 계좌 잔액이 0원인 은경이에게 5,000을 이체하는, 계좌이체 트랜잭션의 수행 시작부터 완료까지의 기록한 로그의 예이다.

source: https://slidesplayer.org/slide/16478540/

장애가 발생하는 시점과 유형이 다양하고, DB를 빠른 시간 내에 복구해야 하므로 실제로 DBMS는 좀 더 복잡하고 효율적인 회복 기법들을 사용한다. DB 회복의 기본 연산인 redo와 undo는 DBMS가 실제로 적용하는 회복 기법들에서 주요 연산으로 사용된다.

source: https://slidesplayer.org/slide/16478540/


1. 로그 회복 기법

로그를 이용한 회복 기법은 데이터를 변경한 연산 결과를 DB에 반영하는 시점에 따라 즉시 갱신 회복 기법지연 갱신 회복 기법으로 나눈다.

1-1. 즉시 갱신 회복 기법

즉시 갱신 회복 기법은 트랜잭션 수행 중에 데이터를 변경한 연산의 결과를 DB에 즉시 반영한다. 그리고 장애 발생에 대비하기 위해 데이터 변경에 대한 내용을 로그 파일에도 기록한다.

DB 회복 시 로그를 정상적으로 사용하려면, 트랜잭션에서 데이터 변경 연산이 실행되었을 때 로그 파일에 로그 레코드를 먼저 기록한 후 DB에 변경 연산을 반영해야 한다.

source: https://slidesplayer.org/slide/16478540/

즉시 갱신 회복 기법은 장애가 발생하면 로그 파일에 기록된 내용을 참조하여, 장애 발생 시점에 따라 redo나 undo 연산을 실행하여 DB를 복구한다. 트랜잭션에 redo 연산을 실행할 것인지, undo 연산을 실행할 것인지는 로그 파일에 기록된 레코드에 따라 결정한다.

  • 트랜잭션이 완료되기 전 장애가 발생할 경우 => undo 연산
    : 로그 파일에 <Ti, start> 로그 레코드는 존재하지만, <Ti, commit> 로그 레코드는 존재하지 않는 상태 => undo 연산 수행

  • 트랜잭션이 완료된 후 장애가 발생한 경우 => redo 연산
    : 로그 파일에 <Ti, start> 로그 레코드와 <Ti, commit> 로그 레코드 모두 존재하는 상태 => redo 연산

1-2. 즉시 갱신 회복 기법 예시

source: https://slidesplayer.org/slide/16478540/

위 그림은 두 개의 트랜잭션을 나타낸 것이다.

트랜잭션 1) A 계좌에서 B 계좌로 1,000원을 이체하는 계좌이체 트랜잭션
트랜잭션 2) C 계좌에서 D 계좌로 2,000원을 이체하는 계좌이체 트랜잭션

그리고 이 두 트랜잭션이 순차적으로 수행된다고 가정한다.

source: https://slidesplayer.org/slide/16478540/

  • 장애 시점 (1)
    : (1) 시점에는 트랜잭션 1의 수행이 아직 완료되기 전이므로 로그 파일에 <T1, start> 로그 레코드만 존재하고, <T1, commit> 로그 레코드는 존재하지 않는다. 그러므로 트랜잭션 1에 undo(트랜잭션 1) 연산을 실행해야 한다. 즉, 로그 내용을 이용하여 지금까지 변경한 데이터의 값을 변경 연산 이전의 값으로 되돌려야 한다. 트랜잭션 1에 undo 연산을 실행하면 DB에서 A 계좌의 잔액이 변경 연산 이전의 값인 5,000원으로 되돌아간다.
    이전 값으로 되돌려야 하는 데이터가 여러 개인 경우에는 로그에 기록된 순서의 반대로 undo 연산을 실행한다.

  • 장애 시점(2)
    : (2) 시점에는 트랜잭션 1의 수행이 이미 완료되었으므로 로그 파일에 <T1, commit> 로그 레코드와 <T1, commit> 로그 레코드 모두 존재한다. 트랜잭션 2은 아직 완료되기 전이므로 <T2, start> 로그 레코드만 존재하고 <T2, commit> 로그 레코드는 존재하지 않는다. 그러므로 트랜잭션 1에 redo(트랜잭션 1) 연산을, 트랜잭션 2dp undo(트랜잭션 2) 연산을 실행해야 한다(회복을 위해 redo, undo 연산 모두 필요할 때는 undo 연산을 먼저 실행한 후 redo 연산을 실행).


지연 갱신 회복 기법

지연 갱신 회복 기법은 트랜잭션이 수행되는 도중 데이터 변경 연산의 결과를 DB에 즉시 반영하지 않고 로그 파일에만 기록해두었다가, 트랜잭션이 부분 완료된 후에 기록된 내용을 이용해 DB에 한번에 반영한다.

트랜잭션이 수행되는 도중 장애가 발생하면 DB에 아직 반영되기 전이므로 로그에 기록된 내용을 버리기만 하면 DB가 원래 상태를 그대로 유지하게 된다. 자연 회복 기법에서는 undo 연산은 필요없고 redo 연산만 필요하므로 로그 레코드에 변경 이전 값을 기록할 필요가 없다. 그러므로 변경 연산 실행에 대한 로그 레코드는 <Ti, X, new_value> 형식으로 기록된다.

  • 트랜잭션이 완료되기 전에 장애가 발생한 경우 => 로그 내용을 무시하고 버림
    : 로그 파일에 <Ti, start> 로그 레코드만 존재하고 <Ti, commit> 로그 레코드는 존재하지 않는 상태

  • 트랜잭션이 완료된 후에 장애가 발생한 경우 => redo 연산 진행
    : 로그 파일에 <Ti, start> 로그 레코드와 <Ti, commit> 로그 레코드가 모두 존재하는 상태

source: https://slidesplayer.org/slide/16478540/

  • 장애 시점 (1)
    : 로그에 기록된 내용을 무시하고 버린다.

  • 장애 시점 (2)
    : 아직 완료되지 않은 트랜잭션 2에 대한 로그 레코드는 무시하며 버리고, 트랜잭션 1에는 redo(트랜잭션 1) 연산을 실행하여 회복한다.


2. 검사 시점 회복 기법

로그를 이용한 회복 기법은 로그 전체를 분석하여 로그에 기록되어 있는 모든 트랜잭션을 대상으로 redo나 undo 중에서 적용할 회복 연산을 결정해야 한다. 그런데 로그 전체를 대상으로 회복 기법을 적용하면 DB 회복에 너무 많은 시간이 걸리고 redo 연산을 수행할 필요가 없는 트랜잭션에도 redo 연산을 실행하는 일이 발생하기도 한다. 이러한 비효울성의 문제를 해결하기 위해 제안된 방법이 검사 시점 회복 기법이다.

source: https://itwiki.kr/w/%EA%B2%80%EC%82%AC%EC%A0%90%ED%9A%8C%EB%B3%B5%EA%B8%B0%EB%B2%95

검사 시점 회복 기법은 로그 회복 기법과 같은 방법으로 로그 기록을 이용하되, 일정 시간 간격으로 검사 시점(checkpoint)을 만들어둔다. 그리고 장애가 발생하면 가장 최근 검사 시점 이전의 트랜잭션에는 회복 작업을 수행하지 않고, 이후의 트랜잭션에만 회복 작업을 수행한다. 검사 시점 회복 기법을 이용하면 회복 작업의 범위가 검사 시점으로 정해지므로 불필요한 회복 작업을 수행하지 않아 DB 회복 시간이 단축되는 장점이 있다.
=> 불필요한 redo 작업을 줄임

일정 시간 간격으로 검사 시점이 되면 메인 메모리에 있는 모든 로그 레코드를 안정 저장 장치에 있는 로그 파일에 기록하고, 트랜잭션의 데이터 변경 내용을 데이터베이스에 반영한다. 그 다음, 검사 시점을 표시하는 <checkpoint L> 형식의 로그 레코드를 로그 파일에 기록한다. <checkpoint L> 형식에서 L은 현재 실행되고 있는 트랜잭션 리스트를 의미한다.

장애가 발생하면 로그 파일에서 가장 최근의 <checkpoint L> 로그 레코드를 찾아 그 이후의 로그 기록에만 회복 작업을 수행한다. <checkpoint L> 로그 레코드를 이용해 회복 작업의 범위를 정하는 것이다. 회복 작업의 범위가 정해지면 즉시 갱신 회복 기법 또는 지연 갱신 회복 기법을 이용해 회복 작업을 수행한다.


3. 미디어 회복 기법

DB는 비휘발성 저장 장치인 디스크에 저장된다. 디스크는 메인 메모리보다 장애가 드물게 발생하지만 디스크 헤더의 고장과 같은 원인으로 장애가 발생할 수 있다. 디스크에 발생할 수 있는 장애에 대비한 회복 기법이 바로 미디어 회복 기법이다.

미디어 회복 기법은 전체 DB의 내용을 일정 주기마다 다른 안전한 저장 장치에 복사해두는 '덤프'를 이용한다. 디스크 장애가 발생하면 가장 최근에 복사해둔 덤프를 이용해 장애 발생 이전의 일관된 DB 상태로 복구한다. 그런 다음 필요에 따라 로그의 내용을 토대로 redo 연산을 실행한다.

전체 DB를 다른 저장 장치에 복사하는 것은 비용이 많이 들고 복사하는 동안에 트랜잭션 수행을 중단해야 하므로 미디어 회복 기법은 CPU가 낭비되는 단점이 있다.

0개의 댓글