트랜잭션 (transaction)
트랜잭션이란?
- 하나의 작업을 수행하기 위해 필요한 데이터베이스의 연산들을 모아놓은 것
- 데이터베이스에서의 논리적인 작업의 단위
- 장애가 발생했을 때 데이터를 복구하는 작업의 단위
트랜잭션의 특성 (ACID)
원자성 (Atomicity)
- 트랜잭션을 구성하는 연산들은 모두 정상적이로 실행되거나 하나도 실행되지 않아야 한다.
만약 트랜잭션 수행 도중 장애가 발생하여 작업을 완료하지 못했다면,
그 시점까지 실행된 모든 연산들의 처리를 취소하고
데이터베이스를 트랜잭션 작업 이전의 상태로 되돌려
트랜잭션의 원자성을 보장해야 한다.
일관성 (Consistency)
- 트랜잭션이 성공적으로 수행된 후에도 데이터베이스가 일관성있는 상태를 유지해야 한다.
- 예시
- 회원 A와 회원 B는 각각 10,000원씩 보유
- 회원 A가 회원 B에게 10,000원 송금
- 일관성 만족 여부에 따른 결과
- 일관성을 만족하는 경우
- 회원 A는 0원, 회원 B는 20,000원 보유
- 일관성을 만족하지 않는 경우
- 회원 A는 0원, 회원 B는 10,000원 보유
- 일관성을 만족하는 경우
트랜잭션이 수행되기 전에 데이터베이스가 일관된 상태였다면
트랜잭션의 수행이 완료된 후 결과를 반영한 데이터베이스도
또 다른 일관된 상태가 되어야 한다.
트랜잭션 수행 중에는 일시적으로 일관된 상태가 아닐 수는 있어도
트랜잭션 수행 완료 시에는 일관된 상태가 되어야 한다.
격리성 (Isolation)
- 현재 수행 중인 트랜잭션이 완료될 때까지
해당 트랜잭션이 생성한 중간 연산 결과에
다른 트랜잭션들이 접근할 수 없다. - 고립성이라고도 부른다.
격리성을 보장하기 위해서는
각 트랜잭션이 순서대로 하나씩 수행되는 것과
같은 결과를 얻을 수 있도록 제어하는 기능이 필요하다.
격리성이 보장됨으로써 사용자들은 트랜잭션들이 동시에 수행되는 것처럼 느끼면서도
순서대로 하나씩 수행되는 것처럼 정확하고 일관된 결과를 얻을 수 있게 된다.
지속성 (Durability)
- 트랜잭션이 성공적으로 완료된 후 데이터베이스에 반영된 수행 결과는
어떠한 경우에도손실되지 않고 영구적이어야 한다. - 영속성이라고도 부른다.
시스템에 장애가 발생하더라도 트랜잭션 작업 결과는 없어지지 않고
데이터베이스에 그대로 남아있어야 한다는 의미를 가진다.
트랜잭션의 지속성을 보장하려면 시스템에 장애가 발생했을 때
데이터베이스를 원래 상태로 복구하는 회복 기능이 필요하다.
트랜잭션의 특성을 지원하는 DBMS의 기능
트랜잭션의 특성 | DBMS의 기능 |
---|---|
원자성 | 회복 기능 |
일관성 | 병행 제어 기능 |
격리성 | 병행 제어 기능 |
지속성 | 회복 기능 |
트랜잭션의 연산
- commit
- 트랜잭션이 성공적으로 수행되었음을 선언한다.
- 작업 완료를 의미한다.
- 트랜잭션이 수행한 최종 결과를 데이터베이스에 반영한다.
- rollback
- 트랜잭션이 수행을 실패했음을 선언한다.
- 작업 취소를 의미한다.
- 데이터베이스를 트랜잭션 수행 전의 일관된 상태로 되돌린다.
트랜잭션의 상태
flowchart TD
A["트랜잭션 수행 시작"] --> B(["활동"])
B --> C(["부분 완료"])
B --> D(["실패"])
C --commit 연산--> E(["완료"])
D --rollback 연산--> F(["철회"])
C --> D
- 활동 상태 (active)
- 트랜잭션이 수행을 시작하여 현재 수행중인 상태
- 부분 완료 상태 (partially committed)
- 트랜잭션의 마지막 연산이 실행된 직후의 상태
- 트랜잭션의 모든 연산을 처리한 상태
- 완료 상태 (committed)
- 트랜잭션이 성공적으로 완료되어 commit 연산을 실행한 상태
- 트랜잭션이 수행한 최종 결과를 데이터베이스에 반영한다.
- 데이터베이스가 새로운 일관된 상태가 되면서 트랜잭션이 종료된다.
- 실패 상태 (failed)
- 하드웨어, 소프트웨어의 문제나 트랜잭션 내부 오류 등의 이유로
장애가 발생하여 트랜잭션의 수행이 중단된 상태 - 트랜잭션이 더는 정상적으로 수행을 계속할 수 없는 상태
- 하드웨어, 소프트웨어의 문제나 트랜잭션 내부 오류 등의 이유로
- 철회 상태 (aborted)
- 트랜잭션의 수행이 실패하여 rollback 연산을 실행한 생태
- 실행했던 트랜잭션의 모든 연산을 취소하고,
데이터베이스를 트랜잭션이 수행되기 이전의 상태로 되돌리면서
트랜잭션이 종료된다. - 철회 상태로 종료된 트랜잭션은 상황에 따라 다시 수행되거나 폐기된다.
- 하드웨어의 이상이나 소프트웨어의 오류로 인한 경우에만 해당한다.
장애와 회복
장애(failure)란?
- 시스템이 제대로 동작하지 안흔 상태
회복(recovery)란?
- 장애가 발생했을 때 데이터베이스를 장애가 발생하기 전의 일관된 상태로 복구시키는 것
데이터베이스 시스템에서 발생할 수 있는 장에의 유형
- 트랜잭션 장애
- 의미
- 트랜잭션 수행 중 오류가 발생하여 정상적으로 수행을 계속할 수 없는 상태
- 원인
- 트랜잭션의 논리적 오류
- 잘못된 대이터 입력
- 시스템 자원의 과다 사용 요구
- 처리 대상 데이터의 부재
- 이외 등등
- 의미
- 시스템 장애
- 의미
- 하드웨어의 결함으로 정상적으로 수행을 계속할 수 없는 상태
- 원인
- 하드웨어의 이상으로 메모리에 저장된 정보가 손실되는 경우
- 하드웨어의 이상으로 교착 상태가 발생한 경우
- 이외 등등
- 의미
- 미디어 장애
- 의미
- 디스크 장치의 결함으로 디스크에 저장딘 데이터베이스의 일부 혹은 전체가 손상된 상태
- 원인
- 디스크 헤드의 손상
- 디스크 헤드의 고장
- 이외 등등
- 의미
회복 기법
- 회복이란 장애가 발생했을 때 데이터베이스를 장애가 발생하기 이전의
모순이 없고 일관된 상태로 복구시키는 것이다. - 회복은 DBMS에 있는 회복 관리자가 담당한다.
- 회복 관리자는 장애 발생을 탐지하고, 장애가 탐지되면 데이터베이스를 복구하는 기능을 제공한다.
- 분류
- 데이터베이스 회복 기법
- 로그 회복 기법
- 즉시 갱신 회복 기법
- 지연 갱신 회복 기법
- 검사 시점 회복 기법
- 미디어 회복 기법
- 로그 회복 기법
- 데이터베이스 회복 기법
회복을 위해 복사본을 만드는 방법
- 데이터베이스 회복의 핵심 원리는 데이터 중복이다.
- 데이터를 별도의 장소에 미리 복사해두고,
장애로 문제 발생 시 복사본을 이용해 원래의 상태로 복원한다. - 종류
- 덤프 (dump)
- 데이터베이스 전체를 다른 저장 장치에 주기적으로 복사하는 방법
- 로그 (log)
- 데이터베이스에서 변경 연산이 실행될 떄마다
데이터를 변경하기 이전 값과 변경한 이후의 값을
별도의 파일에 기록하는 방법
- 데이터베이스에서 변경 연산이 실행될 떄마다
- 덤프 (dump)
회복을 위한 연산
- redo (재실행)
- 가장 최근에 저장한 데이터베이스 복사본을 가져온 후
로그를 이용해 복사본이 만들어진 이후에 실행된 모든 변경 연산을 재실행하여
장애가 발생하기 직전의 데이터베이스 상태로 복구한다. - 전반적으로 손상된 경우에 주로 사용한다.
- 가장 최근에 저장한 데이터베이스 복사본을 가져온 후
- undo (취소)
- 로그를 이용해 지금까지 실행된 몯느 변경 연산을 취소하여
데이터베이스를 원래의 상태로 복구한다. - 변경 중이었거나 이미 변경된 내용만 신뢰성을 잃은 경우에 주로 사용한다.
- 로그를 이용해 지금까지 실행된 몯느 변경 연산을 취소하여
로그 레코드의 종류
- <T, start>
- 트랜잭션 T가 수행을 시작했음을 기록
- <T, X, old_value, new_value>
- 트랜잭션 T가 데이터 X를 이전 값(old_value)에서 새로운 값(new_value)으로
변경하는 연산을 실행했음을 기록
- 트랜잭션 T가 데이터 X를 이전 값(old_value)에서 새로운 값(new_value)으로
- <T, commit>
- 트랜잭션 T가 성공적으로 완료되었음을 기록한다.
- <T, abort>
- 트랜잭션 T가 철회되었음을 기록한다.
로그 회복 기법
- 즉시 갱신 기법 (immediate update)
- 트랜잭션 수행 중에 데이터를 변경한 연산의 결과를 데이터베이스에 즉시 반영한다.
- 장애 발생에 대비하기 위해 데이터 변경에 대한 내용을 로그 파일에도 기록한다.
- 트랜잭션이 완료되기 전에 장애가 발생한 경우에는 undo 연산을 실행한다.
- 트랜잭션이 완료된 후에 장애가 발생한 경우에는 redo 연산을 실행한다.
- 지연 갱신 기법 (defferred update)
- 트랜잭션이 수행되는 도중 데이터 변경 연산의 결과를
데이터베이스에 즉시 반영하지 않고 로그 파일에만 기록해두었다가,
트랜잭션이 부분 완료된 후에 로그에 기록된 내용을 이용해 데이터베이스에 한꺼번에 반영한다. - 트랜잭션이 완료되기 전에 장애가 발생한 경우에는 로그 내용을 무시하고 버린다.
- 트랜잭션이 완료된 후에 장애가 발생한 경우에는 redo 연산을 실행한다.
- 트랜잭션이 수행되는 도중 데이터 변경 연산의 결과를
- 검사 시점 회복 기법
- 로그 회복 기법과 같은 방법으로 로그 기록을 이용하되,
일정 시간 간격으로 검사 시점(checkpoint)을 만들어 둔다. - 장애 발생 시 가장 최근 검사 시점 이전의 트랜잭션에는 회복 잡업을 수행하지 않고,
이후의 트랜잭션에만 회복 잡업을 수행한다.
로그 전체를 대상으로 회복 기법 적용 시 데이터베이스 회복에 너무 많은 시간이 걸리고,
redo 연산을 수행할 필요가 없는 트랜잭션에도 redo 연산을 실행하는 일이 발생하기도 때문에
이러한 비효율성의 문제를 해결하기 위해 제안된 방법이 검사 시점 회복 기법이다. - 로그 회복 기법과 같은 방법으로 로그 기록을 이용하되,
- 미디어 회복 기법
- 전체 데이터베이스의 내용을 일정 주기마다 다른 안전한 저장 장치에 복사해두는 덤프를 이용한다.
- 디스크 장애 발생 시 가장 최근에 복사해둔 덤프를 이용해 장애 발생 이전의 일관된 데이터베이스 상태로 복구한다.
- 덤프를 통한 복구 후 필요에 따라 로그의 내용을 토대로 redo 연산을 실행한다.
- 비용이 많이 들고, 복사하는 동안에는 트랜잭션 수행을 중단해야 되므로 CPU가 낭비되는 단점이 있다.
- 디스크에 발생할 수 있는 장애에 대한 회복 기법이다.
병행 제어
관련 용어
- 병행 수행 (concurrency)
- DBMS에서 지원하는 여러 사용자가 DB를 동시에 공유할 수 있도록 여러 개의 트랜잭션이 동시에 수행되는 기능
- 여러 트랜잭션들이 차례대로 번갈아가며 실행되는 인터리빙(interleaving) 방식으로 진행된다.
- 병행 제어 (concurrency control)
- 여러 개의 트랜잭션이 병행 수행되면서 같은 데이터에 접근하여 연산을 실행하더라도,
문제가 발생하지 않고 정확한 수행 결과를 얻을 수 있도록 트랜잭션의 수행을 제어하는 것 - 동시성 제어라고도 부른다.
- 여러 개의 트랜잭션이 병행 수행되면서 같은 데이터에 접근하여 연산을 실행하더라도,
병렬 수행의 문제
- 갱신 분실 (lost update)
- 하나의 트랜잭션이 수행한 데이터 변경 연산의 결과를
다른 트랜잭션이 덮어써서 변경 연산이 무효화 되는 것
- 하나의 트랜잭션이 수행한 데이터 변경 연산의 결과를
- 모순성 (inconsistency)
- 하나의 트랜잭션이 여러 개의 데이터 변경 연산을 실행할 때,
일관성 없는 데이터베이스에서 데이터를 가져와 연산을 실행함으로써 모순된 결과가 발생하는 것 - 트랜잭션 T가 연산 A와 연산 B를 실행할 때,
연산 A는 트랜잭션 작업 전의 데이터를 통해서 실행되고,
연산 B는 트랜잭션 작업 후의 데이터를 가져와서 실행하는 경우가 이에 속한다.
- 하나의 트랜잭션이 여러 개의 데이터 변경 연산을 실행할 때,
- 연쇄 복귀 (cascading rollback)
- 트랜잭션이 완료되기 전에 장애가 발생하여 rollback 연산을 수행했을 때,
해당 트랜잭션이 장애가 밸생하기 전에 변경한 데이터를 가져가서 변경 연산을 실행한
또 다른 드랜잭션에도 rollback 연산을 연쇄적으로 실행해야 하는 경우 - 트랜잭션 T1과 트랜잭션 T2가 있는데 T1이 rollback을 실행하기 전에 T2가 먼저 commit을 해버리면
T2는 rollback 연산을 실행할 수가 없어서 큰 문제가 발생하게 된다.
- 트랜잭션이 완료되기 전에 장애가 발생하여 rollback 연산을 수행했을 때,
트랜잭션 스케줄
- 트랜잭션에 포함되어 있는 연산들을 수행하는 순서
- 종류
- 직렬 스케줄 (serial schedule)
- 인터리빙 방식을 이용하지 않고 각 트랜잭션별로 연산들을 순차적으로 실행시키는 것
- 모든 트랜잭션이 완료될 때까지 다른 트랜잭션의 방해를 받지 않고 독립적으로 수행된다.
- 항상 모순이 없는 정확한 결과를 얻는다.
- 병행수행으로 취급하지 않아서 일반적으로 잘 사용하지 않는다.
- 비직렬 스케줄 (nonserial schedule)
- 인터리빙 방식을 이용하여 트랜잭션들을 병행해서 수행시키는 것
- 트랜잭션이 돌아가면서 연산들을 실행하기 때문에
하나의 트랜잭션이 환료되기 전에 다른 트랜잭션의 연산이 실행될 수 있다. - 최종 수행 결과의 정확성을 보장할 수 없다.
- 갱신 분실, 모순성, 연쇄 복귀 등의 문제가 발생할 수 있기 때문이다.
- 직렬 가능 스케줄 (serializable schedule)
- 직렬 스케줄과 같이 정확한 결과를 생성하는 비직렬 스케줄
- 모든 비직렬 스케줄이 직렬 가능한 것은 아니다.
- 직렬 가능 스케줄을 이용해 트랜잭션을 병행 수행해야 하지만,
직렬 가능 스케줄인지를 판단하기가 쉽지 않다.- 다수의 트랜잭션을 대상으로 비직렬 스케줄을 찾아내는 것은 어렵다.
- 하나씩 수행해보면서 직렬 스케줄과 같은 결과가 나오는지 확인하는 것도 간단하지 않다.
- 대부분의 DBMS에서는 직렬 가능 스케줄인지를 검사하기 보다는 직렬 가능성을 보장하는 병행 제어 기법을 사용한다.
- 직렬 스케줄 (serial schedule)
로킹 기법
- 병행 수행되는 트랜잭션들이 동일한 데이터에 동시에 접근하지 못하도록
lock과 unlock이라는 두 개의 연산을 이용하는 병행 제어 기법 - 한 트랜잭션이 먼저 접근한 데이터에 대한 모든 연산을 마칠때까지,
해당 데이터에 다른 트랜잭션이 접근하지 못하도록 상호배제(mutual exclusion)하여
직렬 가능성을 보장하는 것이 기본 원리 - lock 연산
- 트랜잭션이 사용할 데이터에 대한 독점권을가지기 위해 사용한다.
- 종류
- 공용(shared) lock
- 데이터에 대한 사용권을 여러 트랜잭션이 함께 가질 수 있게 한다.
- 전용(exclusive) lock
- 데이터에 대한 사용권을 해당 트랜잭션이 독점하도록 한다.
- 공용(shared) lock
- unlock 연산
- 트랜잭션이 데이터에 대한 독점권을 반납하기 위해 사용한다.
- 시스템에 따라서 lock 연산을 실행하는 대상 데이터의 크기인
로깅 단위를 적절하게 선택하는 것이 중요하다.
2단계 로킹 규약 (2PLP)
- 기본 로킹 규약의 문제를 해결하고 트랜잭션의 직렬 가능성을 보장하기 위해
lock 연산과 unlock 연산의 수행 시점에 대한 새로운 규약을 추가한 것 - 트랜잭션 스케줄의 모든 트랜잭션이 2단계 로킹 규약을 준수하면
해당 스케줄은 직렬 가능성이 보장된다. - 2단계 로킹 규약의 전략
- 확장 단계
- 트랜잭션이 lock 연산만 실행할 수 있고, unlock 연산은 실행할 수 없는 단계
- 축소 단계
- 트랜잭션이 unlock 연산만 실핼할 수 있고, lock 연산은 실핼할 수 없는 단계
- 확장 단계
- 트랜잭션이 처음에 수행되면 확장 단계로 들어간다.
- 교착 상태는 처음부터 발생하지 않도록 예방하거나,
발생했을 때 빠르게 탐지하여 필요한 조치를 취하는 방법으로 해결한다.