Chapter 08 트랜잭션, 동시성 제어, 회복
트랜잭션
트랜잭션의 개념
- DBMS에서 데이터를 다루는 논리적인 작업의 단위이다.
- 트랜잭션은 장애 발생 시 데이터를 복구하는 작업의 단위가 된다.
- 트랜잭션은 여러 작업이 동시에 같은 데이터를 다룰 때, 이를 서로 분리하는 단위가 된다.
중요한 점
- 데이터베이스의 데이터는 하드디스크에 저장되어 있다.
- 처리를 위해서는 반드시 주기억장치 버퍼로 사본을 읽어와야 한다는 점이다.
예) 계좌이체 트랜잭션 수행과정
START TRANSACTION
/* 1. 박지성 계좌를 읽어온다. */
/* 2. 김연아 계좌를 읽어온다. */
/* 3. 예금인출 박지성 */
UPDATE Customer
SET balance=balance-10000
WHERE name='박지성';
/* 4. 예금입금 김연아 */
UPDATE Customer
SET balance=balance+10000
WHERE name='김연아';
COMMIT /* 부분 완료-트랜잭션의 종료를 사용자나 다른 트랜잭션에게 알리는 단계 */
/* 5. 박지성 계좌를 기록한다.
/* 6. 김연아 계좌를 기록한다.
- 위와 같이 작성하면 DBMS는 두 문장이 모두 수행되거나 모두 수행되지 않도록 지원한다.
수행과정 정리
- 트랜잭션은 데이터베이스에 저장된 테이블을 읽어와
- 주기억장치 버퍼에 저장하고,
- 버퍼에 저장된 데이터를 수정한 후
- 최종적으로 데이터베이스에 다시 저장한다.
트랜잭션의 성질
- 원자성(Atomicity): 트랜잭션에 포함된 작업은 전부 수행되거나 전부 수행되지 않아야 한다.
- 일관성(Consistency): 트랜잭션을 수행하기 전이나 후나 데이터베이스는 항상 일관된 상태를 유지해야 한다.
- 고립성(Isolation): 수행 중인 트랜잭션에 다른 트랜잭션이 끼어들어 변경중인 데이터 값을 훼손하지 않아야한다.
- 지속성(Durability): 수행을 성공적으로 완료한 트랜잭션은 변경한 데이터를 영구히 저장해야 한다.
원자성
- 트랜잭션에 포함된 작업은 전부 수행되거나 전부 수행되지 않아야 한다.
- SQL에서는 트랜잭션의 시작과 끝을 표시
START TRANSACTION ... COMMIT
문 사용 - 트랜잭션 중간에 작업이 잘못되면 회복 알고리즘을 이용하여 변경한 내용을 취소한다.
- 자의적으로 트랜잭션을 취소하는 명령어 ROLLBACK을 사용하기도 한다.
MySQL의 트랜잭션 제어 명령어(TCL)
표준 명령어 | 문법 | 설명 |
---|---|---|
START TRANSACTION | SET TRANSACTION | 트랜잭션의 시작 |
COMMIT | COMMIT | 트랜잭션의 종료 |
ROLLBACK | ROLLBACK {TO } | 트랜잭션을 전체 혹은 savepoint>까지 무효화시킴 |
SAVE | SAVEPOINT | 를 만듦 |
- 트랜잭션의 길이가 길면 트랜잭션의 중간 지점에 수정내용을 반영하는 포인트를 만든다.
- 이를 SAVEPOINT(저장점) 이라고 한다.
- 트랜잭션이 잘못되어 처음부터 다시 실행해야 할 경우 트랜잭션의 처음이 아니라 SAVEPOINT까지 되돌아가면 트랜잭션 전체가 ROLLBACK되는 것을 막을 수 있다.
일관성
- 트랜잭션을 수행하기 전이나 후나 데이터베이스는 항상 일관된 상태를 유지해야 한다.
- CREATE 문과 ALTER 문의 무결성 제약조건을 통해 명시된다.
고립성
- 데이터베이스는 공유가 목적이기 때문에 여러 트랜잭션이 동시에 수행된다.
- 이때, 각 트랜잭션은 다른 트랜잭션의 방해를 받지 않고 독립적으로 작업을 수행한다.
- 이렇게 여러 트랜잭션이 동시에 수행될 때 상호 간섭이나 데이터 충돌이 일어나지 않는 현상을 고립성이라고 한다.
- 고립성을 유지하기 위해서는 변경 중인 임시 데이터를 다른 트랜잭션이 읽거나 쓰려고 할 때 제어하는 작업이 필요하다.
동시성 제어
- 동시에 수행되는 트랜잭션이 같은 데이터를 가지고 충돌하지 않도록 제어하는 작업
지속성
- 수행을 성공적으로 완료한 트랜잭션은 변경한 데이터를 영구히 저장해야 한다.
- DBMS 복구 시스템은 트랜잭션이 작업한 내용을 수시로 로그 데이터베이스에 기록하였다가 문제가 발생하면 로그 파일을 이용하여 복구 작업을 수행한다.
- 즉, 시스템이 멈추어도 트랜잭션 수행으로 변경된 내용은 디스크에 기록된다.
개별 상태
- 활성(Active) : 트랜잭션이 정상적으로 실행중인 상태를 의미한다.
트랜잭션이 시작되면, 해당 트랜잭션의 상태는 활동(Active)상태가 된다.
해당 상태는 설계자가 설계한 대로 연산들이 정상적으로 실행중인 상태를 의미한다.
- 작업 성공시,
2-1. 부분 완료(Partially Committed) : 트랜잭션의 마지막까지 실행되었지만, Commit 연산이 실행되기 직전의 상태
2-2. 완료(Committed) : 트랜잭션이 성공이 종료되어 Commit 연산을 실행한 후의 상태
설계된 트랜잭션대로 명령을 성공적으로 수행하면 그 다음 상태는 부분적 완료(Partially Committed)상태가 된다.
설계된 작업대로 작업이 성공하였다고 하여 무조건 반영하는 것이 아니라, 설계자의 최종 승인(Commit)이 있을 때 까지 실제 데이터베이스에 작업 내용을 반영하지 않고 기다리고 있는 상태이다.
설계자가 작업 결과에 대하여 반영을 승인(Commit)한다면 트랜잭션이 성공적으로 종료된다(Committed)
- 작업 실패시,
2-1. 실패(Failed) : 트랜잭션 실행에 오류가 발생하여 중단된 상태.
2-2. 철회(Aborted) : 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태.
트랜잭션을 수행하는 중간에 모종의 원인으로 인하여 오류가 발생하여 실행이 중단된 상태를 실패(Failed)상태라고 한다.
이때 트랜잭션이 비정상적으로 종료되었으니, 설계되어있는 트랜잭션 내부의 작업을 다시 수행 이전의 상태로 돌리는 (ROLLBACK) 연산을 수행하면 그 상태를 철회(Aborted)라고 한다.
Commit
- Commit이란, 모든 작업들을 정상 처리하겠다고 확정하는 명령어로서, 해당 처리 과정을 DB에 영구 저장하겠다는 의미한다.
- Commit을 수행하면 하나의 트랜잭션 과정이 종료되는 것이다.
- Commit을 수행하면 이전 데이터가 완전히 반영되어 UPDATE된다.
Roll-back
- Roll-back은 작업 중 문제가 발생되어 트랜잭션의 처리 과정에서 발생한 변경사항을 취소하는 명령어이다.
- 해당 명령을 트랜잭션에게 하달하면, 트랜잭션은 시작되기 이전의 상태로 되돌아간다.
- 이것은 마지막 Commit을 완료한 시점으로 돌아간다는 말과 상통한다.
- 즉, Rollback은 Commit하여 저장한 예전 상태를 복구하는 것이다.
트랜잭션의 성질과 DBMS의 기능 연결
동시성 제어
- 동시성 제어(concurrency control): 트랜잭션이 동시에 수행될 때, 일관성을 해치지 않도록 트랜잭션의 데이터 접근을 제어하는 DBMS의 기능
갱신손실 문제
- 갱신손실 (lost update): 두 개의 트랜잭션이 한 개의 데이터를 동시에 갱신(update)할 때 발생, 데이터베이스에서 절대 발생하면 안 되는 현상
작업설명: 한 개의 데이터에 두 개의 트랜잭션이 접근하여 갱신하는 작업
시나리오: 두 개의 트랜잭션이 동시에 작업을 진행
문제 발생: 갱신손실
- T2는 잘못된 데이터로 작업하여 잘못된 결과를 만든 다음 T1의 갱신 작업을 무효화하고 덧쓰기를 수행했다.
- T1의 갱신이 손실된 갱신 손실 문제가 발생한 것이다.
락
- 갱신손실 문제를 해결하려면 상대방 트랜잭션이 데이터를 사용하는지 여부를 알 수 있는 규칙이 필요하다.
락의 개념
- 락(lock): 데이터를 수정 중이라는 사실을 알리는 방법의 잠금 장치
- T1이 X에 락을 설정하였기 때문에 T2는 자신이 원하는 락을 얻지 못하고 대기한다.
- T2는 T1이 X의 락을 해지(언락)하면 진행할 수 있다.
- 락을 사용하면 데이터 X에 대한 갱신을 순차적으로 진행할 수 있기 때문에 갱신손실 문제를 해결할 수 있다.
락의 유형
- 락은 트랜잭션이 읽기만 할 때 사용하는 락인 공유락(LS, shared lock) 과 읽고 쓰기를 할 때 사용하는 배타락(LX, exclusive lock) 으로 나뉜다.
공유락과 배타락을 사용하는 규칙
- 데이터에 락이 걸려있지 않으면 트랜잭션은 데이터에 락을 걸 수 있다.
- 트랜잭션이 데이터 X를 읽기만 할 경우 LS(X)를 요청하고, 읽거나 쓰기를 할 경우 LX(X)를 요청한다.
- 다른 트랜잭션이 데이터에 LS(X)를 걸어둔 경우, LS(X)의 요청은 허용하고 LX(X)는 허용하지 않는다.
- 다른 트랜잭션이 데이터에 LX(X)를 걸어둔 경우, LS(X)와 LX(X) 모두 허용하지 않는다.
- 트랜잭션이 락을 허용받지 못하면 대기 상태가 된다.
2단계 락킹
- 락을 사용하면 갱신손실 문제를 해결할 수 있다.
- 하지만, 락을 걸고 해제하는 시점에 제한을 두지 않을 경우 두 개의 트랜잭션이 동시에 실행될 때 데이터의 일관성이 깨질 수 있다.
- 즉, 데이터에 락을 걸었다 풀고 다시 거는 중간 과정에 락의 해지 상태가 생기면서 다른 트랜잭션에게 중간 결과를 보일 수 있다는 것이다.
이를 방지하기 위한 것이 2단계 락킹
- 확장단계(Growing phase, Expanding phase): 트랜잭션이 필요한 락을 획득하는 단계로, 이 단계에서는 이미 획득한 락을 해제하지 않는다.
- 수축단계(Shrinking phase): 트랜잭션이 락을 해제하는 단계로, 이 단계에서는 새로운 락을 획득하지 않는다.
작업 설명: 두 개의 데이터에 두 개의 트랜잭션이 접근하여 갱신하는 작업 (A+B=2200이라는 일관성이 보장되어야 함.)
문제 발생: 락을 사용하되 2단계 락킹 기법을 사용하지 않을 경우
A+B=2190으로 일관성 제약 조건에 위배됨.
문제 해결: 2단계 락킹 기법을 사용할 경우
- 해결방법은 트랜잭션이 작업을 완료하기 전에는 락을 해제하지 않는 것이다.
- 즉, 확장단계에는 락을 걸기만 하고, 수축단계에는 락을 해지하기만 한다.
데드락
- 데드락(deadlock): 두 개 이상의 트랜잭션이 각각 자신의 데이터에 대하여 락을 획득하고 상대방 데이터에 대하여 락을 요청하면 무한 대기 상태에 빠질 수 있는 현상. 교착상태라고도 한다.
작업 설명: 두 개의 데이터에 두 개의 트랜잭션이 접근하여 갱신하는 작업
문제 발생: 데드락 발생
문제 해결: 데드락 해결
- 일반적으로 데드락이 발생하면 DBMS는 T1 혹은 T2의 작업 중 하나를 강제 중지시킨다.
- 나머지 트랜잭션은 정상적으로 실행되고, 중지시키는 트랜잭션에서 변경한 데이터는 원래 상태로 되돌려 놓는다.
트랜잭션 고립 수준
T1은 읽기만 하고, T2는 읽고 쓰기 모두 할 때 발생할 수 있는 문제에 대해 다룬다.
트랜잭션 동시 실행 문제
- 오손 읽기(dirty read) 문제
- 반복불가능 읽기 문제
- 유령 데이터 읽기 문제
읽기만 하는 트랜잭션이 쓰기 트랜잭션에서 작업한 중간 데이터를 읽기 때문에 발생하는 문제들이다.
오손 읽기
- 읽기 작업을 하는 트랜잭션 1이 쓰기 작업을 하는 트랜잭션 2가 작업하는 중에 중간 데이터를 읽기 때문에 생기는 문제
- 작업 중인 트랜잭션 2가 어떤 이유에서 작업을 철회(ROLLBACK)할 경우 트랜잭션 1은 무효가 된 데이터를 읽게 되고 잘못된 결과를 도출하는 현상
작업 설명: 두 개의 트랜잭션을 동시에 실행
- 트랜잭션 T1, T2가 동시에 실행된다. T1은 읽기만 하고 T2는 쓰기를 한다.
- T1은 T2가 변경한 데이터를 읽어와 작업하는데, T2가 작업 중 철회(ROLLBACK)을 하게 되었다.
문제 발생: 오손읽기
- T2가 변경한 데이터를 T1이 읽은 후 어떤 원인으로 인하여 T2가 스스로 철회(ROLLBACK)를 하게 되었다.
- 철회를 하면 T2의 작업은 없던 일이 된다.
- T1은 T2가 종료하지 않은 상태에서 T2가 변경한 데이터를 보고 작업을 하게 된 것이다.
- 잘못된 부분 3행: T2가 age를 21로 수정하고 롤백을 시킬려고 했는데 3행에서 롤백시킬 데이터를 무턱대고 읽어버렸다.
반복불가능 읽기 (non-repeatable read)
- 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고(갱신, UPDATE) 트랜잭션 1이 다시 한 번 데이터를 읽을 때 생기는 문제이다.
- 트랜잭션 1이 읽기 작업을 다시 한 번 반복하는 작업일 경우 이전의 결과와 다른 결과가 나오는 현상이다.
작업 설명: 두 개의 트랜잭션을 동시에 실행
- 트랜잭션 T1, T2가 동시에 실행된다. T1은 읽기만 하고 T2는 쓰기(갱신, UPDATE)를 한다.
- T1은 데이터를 읽고 작업을 한 후, T2가 변경한 데이터를 다시 한 번 읽어와 작업을 한다.
문제 발생: 반복불가능 읽기
- T1이 데이터를 읽고 작업하던 중 T2가 데이터를 변경하였다.
- T1은 변경한 데이터를 보고 다시 한 번 작업을 하였다.
- 오손 읽기와 달리 이번에는 T2가 COMMIT를 했기 때문에 틀린 데이터는 아니다.
- 그런데 T1 입장에서는 같은 SQL 문이 다른 결과를 도출한다.
유령데이터 읽기(phantom read)
- 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고(삽입, INSERT) 트랜잭션 1이 다시 한 번 데이터를 읽을 때 생기는 문제이다.
- 트랜잭션 1이 읽기 작업을 다시 한 번 반복할 경우 이전에 없던 데이터(유령데이터)가 나타나는 현상이다.
작업 설명: 두 개의 트랜잭션을 동시에 실행
- 트랜잭션 T1은 읽기만 하고 T2는 쓰기(삽입, INSERT)를 한다.
- T1은 데이터를 읽고 작업을 한 후, T2가 변경한 데이터를 다시 한 번 읽어와 작업을 한다.
문제 발생: 유령데이터 읽기
- 이번에는 T1이 T2가 새로운 데이터를 삽입한 사실을 모르고 작업을 한다.
- T2가 COMMIT을 했기 때문에 틀린 데이터는 아니다.
- 그러나 T1입장에서는 새로운 데이터가 반영되어 반복불가능 읽기와 마찬가지로 같은 SQL문이 다른 결과를 도출한다.
- 유령데이터 읽기는 반복불가능 읽기와 비슷하지만 없던 데이터가 삽입 되었기 떄문에 다르게 구분한다.
참고💡
MySQL은 유령데이터 읽기가 발생하지 않는다. MySQL의 REPEATABLE READ는 트랜잭션이 처음 데이터를 읽어올 때 SNAPSHOT을 구축하여 자료를 가져오며 그에 따라 다른 세션의 자료가 변경되더라도 동일한 경과를 보여주게 된다.w
트랜잭션 고립 수준 명령어
- DBMS는 트랜잭션을 동시에 실행시키면서 락보다 좀 더 완화된 방법을 문제를 해결하기 위해 제공하는 명령어
READ UNCOMMITTED (LEVEL = 0)
- 고립 수준이 가장 낮은 명령어로, 자신의 데이터에 아무런 공유락을 걸지 않는다.(베타락은 갱신손실 문제 때문에 걸어야 한다.).
- 또한 다른 트랜잭션에 공유락과 베타락이 걸린 데이터를 대기하지 않고 읽는다.
- 심지어 다른 트랜잭션이 COMMIT하지 않은 데이터도 읽을 수 있다.
- 그 때문에 오손(dirty) 페이지의 데이터를 읽게 된다.
- 이 명령어는 SELECT 질의의 대상이 되는 테이블에 대해서 락을 설정하지 않은 것(NOLOCK)과 같다.
READ COMMITTED (LEVEL=1)
- 오손(dirty) 페이지의 참조를 피하기 위해 자신의 데이터를 읽는 동안 공유락을 걸지만 트랜잭션이 끝나기 전에라도 해지 가능하다.
- 다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행한다.
- 이 옵션은 오라클의 기본 설정으로 아무런 설정을 하지 않으면 READ COMMITTED 방식으로 수행된다.
REPEATABLE READ (LEVEL=2)
- 자신의 데이터에 설정된 공유락과 배타락을 트랜잭션이 종료할 때까지 유지하여 다른 트랜잭션이 자신의 데이터를 갱신(UPDATE)할 수 없도록 한다.
- 다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행한다.
- 다른 고립화 수준에 비해 데이터의 동시성(concurrency)이 낮아 특별하지 않은 상황이라면 사용하지 않는 것이 좋다.
SERIALIZABLE (LEVEL=3)
- 고립 수준이 가장 높은 명령어로, 실행 중인 트랜잭션은 다른 트랜잭션으로부터 완벽하게 분리된다.
- 데이터 집합에 범위를 지어 잠금을 설정할 수 있기 때문에 다른 사용자가 데이터를 변경하려고 할 때 트랜잭션을 완벽하게 분리할 수 있다.
- 이 명령어는 네 가지 고립화 수준 중 제한이 가장 심하고 데이터의 동시성도 낮다. 이 명령어는 SELECT 질의의 대상이 되는 테이블에 미리 배타락을 설정한 것과 같은 효과를 낸다.
실습
반복불가능 읽기 문제와 해결방안
- 트랜잭션 T1에 공유락을 걸고 끝까지 유지하였기 때문에 트랜잭션 T2의 UPDATE동작은 T1이 COMMIT를 하고나서 수행하게 된다.
- REPEATABLE READ 모드 사용
좌) 반복불가능 읽기 문제, 우) 해결방안
유령데이터 읽기 문제와 해결방안
- 트랜잭션 T1인덱스에 공유락을 설정하여 다른 트랜잭션인 트랜잭션T2의 INSERT가 금지된다.
REPEATABLE READ로 상향하면 반복불가능 읽기 문제는 해결할 수 있지만, 새로운 데이터가 삽입되어 발생하는 유령데이터 읽기 문제는 해결할 수 없다.
- SERIALIZABLE 모드 사용
회복
- 회복(recovery): 데이터베이스에 장애가 발생했을 때 데이터베이스를 일관성 있는 상태로 되돌리는 DBMS의 기능
데이터베이스 시스템에서 발생할 수 있는 장애 유형
- 시스템충돌: 하드웨어 혹은 소프트웨어의 오류로 인하여 주기억장치가 손실되는 것을 말한다. 주기억장치에 상주하여 처리 중인 프로그램과 데이터의 일부 혹은 전부가 손실된다.
- 미디어 장애: 헤드의 충돌이나 읽기 장애에 의하여 보조기억장치의 일부 데이터가 손실되는 것을 말한다. 보조기억장치에 저장 중인 데이터의 일부 혹은 전부가 손실된다.
- 응용 소프트웨어 오류: 데이터베이스에 접근하는 소프트웨어의 논리적인 오류로 트랜잭션의 수행이 실패하는 것을 말한다.
- 자연재해: 화재, 홍수, 지진, 정전 등에 의해 컴퓨터 시스템이 손상되는 것을 말한다.
- 부주의 혹은 태업(sabotage): 운영자나 사용자의 부주의로 데이터가 손실되거나 의도적인 손상을 입는 것을 말한다.
트랜잭션과 회복
- 트랜잭션은 데이터베이스 회복의 단위
- 트랜잭션은 데이터의 변경 내용을 한순간에 모두 데이터베이스에 기록하지 않는다.
- 변경한 내용(버퍼)을 로그(임시 디스크)에 기록한 후 데이터베이스에 반영
- B-1: 정상 실행, C-1: run time error, C-2: roll back, D-2,C-2: recovery
로그 파일
- DBMS는 트랜잭션이 수행 중이거나 수행이 종료된 후 발생하는 데이터베이스 손실을 방지하기 위해 트랜잭션의 데이터베이스 기록을 추적하는 로그 파일(log file)을 사용한다.
- 로그 파일은 트랜잭션이 반영한 모든 데이터의 변경사항을 데이터베이스에 기록하기 전에 미리 기록해두는 별도의 데이터베이스이다. 안전한 하드디스크에 저장되며 전원과 관계없이 기록이 남아있다.
- 로그 파일에 저장된 로그의 구조는 다음과 같다.
- <트랜잭션번호, 로그의 타입, 데이터 항목 이름, 수정 전 값, 수정 후 값>
- '로그의 타입’은 트랜잭션의 연산 타입으로 START, INSERT, UPDATE, DELETE, ABORT, COMMIT 등이 있다.
- ‘수정 전 값’은 데이터의 변경 전 값을 나타내고, ‘수정 후 값’은 연산의 결과로 변경된 값을 나타낸다.
로그 파일을 이용한 회복
- 데이터의 변경 기록을 저장해 둔 로그 파일을 이용하면 시스템 장애도 복구할 수 있다.
- 아래 두 개의 트랜잭션이 실행된다고 하자. 트랜잭션은 각각 데이터 A,B,C,D를 읽거나 쓰는 작업을 진행한다.
- 데이터 A,B,C,D 의 초깃값은 100,200,300,400이다.
- 트랜잭션이 T1->T2 순으로 실행된다면 다음과 같은 로그 파일이 생성된다.
- 참고로 트랜잭션의 write가 수행될 때 로그에 기록된다.
- 결국엔 write 동작이 로그에 기록하는 명령
로그 파일을 이용한 회복 방법
- 시스템 운영 중 장애가 발생하여 시스템이 다시 가동되었을 때 DBMS는 로그 파일을 먼저 살펴본다.
- DBMS는 트랜잭션이 종료되었는지 혹은 중단되었는지 여부를 판단하여 종료된 트랜잭션은 종료를 확정하기 위하여 재실행(REDO)을 진행하고, 중단된 트랜잭션은 없던 일로 되돌리기 위해 취소(UNDO)를 진행한다.
트랜잭션의 재실행(REDO)
- 장애가 발생한 후 시스템을 다시 가동을 했을 때, 로그 파일에 트랜잭션 시작(START)이 있고 종료(COMMIT)가 있는 경우다.
- COMMIT 연산이 로그에 있다는 것은 트랜잭션이 모두 완료되었다는 의미다. 다만 변경 내용이 버퍼에서 데이터베이스에 기록되지 않았을 가능성이 있다.
- 따라서 로그를 보면서 트랜잭션이 변경한 내용을 데이터베이스에 다시 기록하는 과정이 필요하다. 이 과정을 REDO라고 한다.
트랜잭션의 취소(UNDO)
- 장애가 발생한 후 시스템을 다시 가동했을 때, 로그 파일에 트랜잭션의 시작(START)만 있고 종료(COMMIT)가 없는 경우다.
- COMMIT 연산이 로그에 보이지 않는다는 것은 트랜잭션이 완료되지 못했다는 의미로, 트랜잭션이 한 일을 모두 취소해야 한다.
- 이 경우 완료하지 못했지만 버퍼의 변경 내용이 데이터베이스에 기록되어 있을 가능성이 있기 때문에 로그를 보면서 트랜잭션이 변경한 내용을 데이터베이스에서 원상복구시켜야 한다.
- 이 과정을 UNDO라고 한다.
즉시 갱신 방법
- 즉시 갱신(immediate update)은 ‘버퍼->로그 파일’, ‘버퍼->데이터베이스’ 작업이 부분완료 전에 동시에 진행될 수 있으며,
- 부분완료 전에 버퍼의 갱신 데이터는 로그에 기록이 진행이 된 상태이며 부분완료 전에 버퍼의 일부 내용이 실제 데이터베이스에 반영될 수 있다.
지연 갱신 방법
- 지연 갱신(deferred update)은 ‘버퍼->로그 파일'이 끝난 후 부분완료를 하고 ‘버퍼->데이터베이스’ 작업이 진행되는 방법이다.
- 부분 완료 전에는 갱신 내용이 실제 데이터베이스에 반영되지 않은 상태이다.
- 지연생신은 즉시갱신과 마찬가지로 부분완료가 되면 최소한 버퍼의 갱신 데이터는 로그에 모두 기록이 끝난 상태지만, 데이터베이스에 반영은 되지 않은 상태이다.
- 지연갱신 방법을 사용하면 데이터베이스에 반영하는 작업은 지연되지만, 장애가 발생할 경우 로그에 START 만 나타나는 트랜잭션은 취소(UNDO) 작업을 할 필요가 없는 장점이 있다.
체크포인트를 이용한 회복
- 로그를 이용한 회복은 시스템에 장애가 일어났을 때 어느 시점까지 되돌아가야 하는지 알 수 없다.
- 트랜잭션이 많은 응용의 경우 하루 이상 되돌아가서 복구하는 것은 사실상 불가능하다.
- 회복 시 많은 양의 로그를 검색하고 갱신하는 시간을 줄이기 위하여 몇 십 분 단위로 데이터베이스와 트랜잭션 로그 파일을 동기화한 후 동기화한 시점을 로그 파일에 기록해두는 방법 혹은 그 시점을 체크포인트(checkpoint, 혹은 검사점)라고 한다.
체크포인트 시점에는 다음과 같은 작업을 진행한다.
- 주기억장치의 로그 레코드를 모두 하드디스크의 로그 파일에 저장한다.
- 버퍼에 있는 변경된 내용을 하드디스크의 데이터베이스에 저장한다.
- 체크포인트를 로그 파일에 표시한다.
체크포인트가 있으면 로그를 이용한 회복 기법은 좀더 간단해짐.
- 체크포인트 이전에 [COMMIT] 기록이 있는 경우(즉시,지연갱신)
- 아무 작업이 필요 없음.
- 로그에 체크포인트가 나타나는 시점은 이미 변경 내용이 데이터베이스에 모두 기록된 후이기 때문.
- 체크포인트 이후에 [COMMIT] 기록이 있는 경우(즉시, 지연갱신)
- REDO(T)를 진행.
- 체크포인트 이후에 변경 내용이 데이터베이스에 반영되지 않았으므로 REDO를 진행.
- 체크포인트 이후에 [COMMIT] 기록이 없는 경우
- 즉시 갱신 방법을 사용했다면 UNDO(T)를 진행.
- 버퍼의 내용이 반영됐을 수도 있기 때문에 원상복구 시켜야 함.
- 반면 지연 갱신 방법을 사용했다면 아무것도 할 필요가 없음.
- 지연 갱신 방법은 [COMMIT] 이전에는 버퍼의 내용을 데이터베이스에 반영하지 않기 때문.
- 즉시 갱신 방법을 사용했다면 T2, T3는 아무 작업이 필요 없고, T4, T5는 REDO, T1, T6는 UNDO가 필요하다
- 지연 갱신 방법을 사용했다면 T2, T3는 아무 작업이 필요 없고, T4, T5는 REDO가 필요함. T1, T6는 아무 작업이 필요 없음.
다른 예시
- 트랜잭션 T1, T2, T3가 동시에 실행된 후 아래의 그림처럼 로그 기록을 남겼다.
- 장애가 발생하고 로그 버퍼에 15번 문장까지 기록이 있을 경우 복구를 시작한다고 한다.
- 이때, 즉시갱신 기법을 사용하여 회복한다면 T1은 아무 작업이 필요없고, REDO(T2), UNDO(T3)가 진행된다.
- 지연갱신 기법을 사용한다면 T1, T3는 아무 작업이 필용벗고 T2는 REDO가 필요하다.
'Develop > Database' 카테고리의 다른 글
DB | DB Locking과 Optimistic Lock/Pessimistic Lock (0) | 2023.09.20 |
---|---|
DB | Join (0) | 2023.09.20 |
DB | 정규화 (0) | 2023.08.28 |
DB | 데이터 모델링 (1) | 2023.08.28 |
DB | 데이터베이스 프로그래밍 (1) | 2023.08.27 |