[데이터베이스] 9. 트랜잭션

Seojin Kwak·2022년 6월 1일
0

Database

목록 보기
6/9

트랜잭션

  • 트랜잭션: 많은 사용자들이 동시에 데이터베이스의 서로 다른 부분 또는 동일한 부분을 접근하면서 데이터베이스 사용
    - 동시성 제어(Concurrency Control)
    : 동시에 수행되는 트랜잭션들이 데이터베이스에 미치는 영향 == 트랜잭션을 순차적으로 수행했을 때 데이터베이스에 미치는 영향
    속도 중앙처리장치 >> 입출력장치 => 다수 사용자가 데이터베이스 동시 접근해도 데이터베이스 일관성 유지 필요
    - 회복(Recovery)
    : 데이터베이스 갱신 도중에 시스템 고장나도 데이터베이스의 일관성 유지
  1. 전체 사원 급여 6% 인상
UPDATE	EMPLOYEE
SET		SALARY = SALARY * 1.06;
  • 500명 전원 급여가 수정 or 아무도 갱신 X
  • 320th 사원까지 수정 후 컴퓨터 시스템 다운 시?
    : DBMS가 추가로 정보 유지하지 않는다면 DBMS 재기동 후 어느 사원까지 튜플 수정되었는지 알 수 X => 로그(log) 유지
  1. 계좌 이체
UPDATE	CUSTOMER
SET		BALANCE = BALANCE - 100000
WHERE	CUST_NAME = '정미림';

UPDATE	CUSTOMER
SET		BALANCE = BALANCE + 100000
WHERE	CUST_NAME = '안명석';
  • 첫번째 UPDATE문 수행 후, 두번째 UPDATE문 수행 전 컴퓨터 시스템 다운 시?
    : 둘 다 수행 or 아무도 수행 X => 하나의 트랜잭션(단위)처럼 DBMS가 보장
  • default: 각각의 SQL문이 하나의 트랜잭션으로 취급
  • 두 개 이상의 SQL문을 하나의 트랜잭션으로 취급하려면 사용자가 명시적으로 표시
  1. 항공기 예약
Begin_transaction Reservation
	begin
    	input(flight_no, date, customer_name);
        EXEC SQL SELECT	SET_SOLD, CAPACITY	// 팔린 좌석 수, 총 좌석 수
        		 INTO	temp1, temp2
                 FROM	FLIGHT
                 WHERE	FNO = flight_no AND DATE = date;
                 
        if temp1 = temp2
        	then output("빈 좌석이 없습니다");
            	Abort
            else
        EXEC SQL UPDATE	FLIGHT
        		 SET	SEAT_SOLD = SEAT_SOLD + 1
                 WHERE	FNO = flight_no AND DATE = date;
        
        EXEC SQL INSERT
        		 INTO	RESERVED(FNO, DATE, CUST_NAME, SPECIAL);
                 VALUES	(flight_no, date, customer_name, null);
        Commit
        output("예약이 완료되었습니다");
	endif
end. {Reservation}
  • 두번째 SQL문 수행 후, 세번째 SQL문 수행 전 컴퓨터 시스템 다운 시?
    : 세 개의 SQL문 모두 수행 or 아무것도 수행 X => 하나의 트랜잭션
  • DBMS는 각 SQL문의 의미를 알 수 없으므로 하나의 트랜잭션으로 취급해야 하는 SQL문들의 범위를 사용자가 명시적으로 표시

트랜잭션 특성 (ACID)

  • 원자성(Atomicity)
    : 한 트랜잭션 내의 모든 연산들이 완전히 수행되거나 전혀 수행되지 않음 (All or Nothing)
    - DBMS 회복 모듈: 시스템 다운 시, 부분적으로 데이터베이스 갱신한 트랜잭션의 영향 취소 => 원자성 보장
    - 완료된 트랜잭션이 갱신한 사항: 트랜잭션 영향 재수행 => 원자성 보장

  • 일관성(Consistency)
    : 어떤 트랜잭션이 수행되기 전에 데이터베이스가 일관된 상태를 가졌다면 트랜잭션이 수행된 후에 데이터베이스는 또 다른 일관된 상태
    - 트랜잭션 수행 도중: 데이터베이스 일시적으로 일과된 상태 갖지 않을 수 있음

  • 고립성(Isolation)
    : 한 트랜잭션이 데이터 갱신하는 동안 이 트랜잭션 완료 전까지 갱신 중인 데이터를 다른 트랜잭션들이 접근하지 못하도록 함
    - 다수의 트랜잭션들이 동시에 수행된 결과 == 어떤 순서에 따라 트랜잭션들을 하나씩 차례대로 수행된 결과
    - DBMS 동시성 제어 모듈이 보장
    - 다양한 고립 수준 제공

  • 지속성(Durability)
    : 일단 한 트랜잭션 완료 시, 이 트랜잭션이 갱신한 것은 그 후에 시스템 고장나도 손실 X
    - 완료된 트랜잭션 효과: 시스템 고장 후에도 데이터베이스에 반영
    - DBMS 회복 모듈이 보장

DBMS 기능특성
무결성 제약조건일관성
동시성 제어일관성, 고립성
회복원자성, 지속성
  • 트랜잭션 완료: 트랜잭션에서 변경하려는 내용이 데이터베이스에 완전하게 반영
    COMMIT WORK
  • 트랜잭션 철회: 트랜잭션에서 변경하려는 내용이 데이터베이스에 일부만 반영된 경우, 원자성 보장 위해 트랜잭션이 갱신한 사항을 트랜잭션 수행 전 상태로 돌림
    ROLLBACK WORK
연산COMMITROLLBACK
의미완료(성공적 종료)철회(비성공적 종료)
DBMS의 트랜잭션 관리 모듈에 알리는 사항1. 트랜잭션의 성공적 종료 2. 데이터베이스는 새로운 일관된 상태 가짐 3. 트랜잭션이 수행한 갱신을 데이터베이스에 반영해야 함1. 트랜잭션의 일부 비성공적 종료 2. 데이터베이스 불일치 상태 가능 3. 트랜잭션이 수행한 갱신이 데이터베이스에 일부 반영 시, 취소해야 함
  • 트랜잭션이 성공하지 못하는 원인
    - 시스템 고장: 중앙처리장치, 주기억장치, 전원공급장치 등의 고장
    - 트랜잭션 고장: 트랜잭션 수행 도중 철회
    - 매체 고장: 디스크헤드, 디스크 컨트롤러 등의 고장. 보조기억장치의 전부 or 일부 내용 지워짐
    - 통신 고장
    - 자연재해
    - 부주의 또는 고의적 고장

동시성 제어

  • 동시성 제어: 여러 사용자들이 다수의 트랜잭션들을 동시에 수행하는 환경에서 부정확한 결과 생성할 수 있는, 트랜잭션들 간의 간섭이 생기지 않도록 함
    - 직렬 스케줄: 여러 트랜잭션들의 집합을 한 번에 한 트랜잭션씩 차례로 수행 (일관성 유지)
    - 비직렬 스케줄: 여러 트랜잭션 동시 수행
    - 직렬 가능: 비직렬 스케줄의 수행 결과 == 직렬 스케줄의 수행 결과

  • 데이터베이스 연산
    - Input(X): 데이터베이스 항목 X를 포함하고 있는 블록을 주기억 장치 버퍼로 읽어들임
    - Output(X): 데이터베이스 항목 X를 포함하고 있는 블록을 디스크에 기록
    - read_item(X): 주기억 장치 버퍼 -> 프로그램 변수 X로 복사
    - write_item(X): 프로그램 변수 X -> 주기억 장치 내의 데이터베이스 항목 X에 기록

  • 동시성 제어를 하지 않고 다수의 트랜잭션을 동시에 수행할 때 생길 수 있는 문제
    - 갱신 손실: 수행 중인 트랜잭션이 갱신한 내용을 다른 트랜잭션이 덮어 씀으로써 갱신 무효

    하나의 SQL문은 DBMS 내에서 여러 개의 명령들로 나뉘어 수행된다. 다수 사용자 환경에서는 여러 사용자들이 동시에 요청한 트랜잭션의 명령들이 섞여서 수행될 수 있다. 트랜잭션 T1은 X에서 Y로 100000을 이체하고, 트랜잭션 T2는 X의 값에 50000을 더하려고 한다. 두 트랜잭션이 수행되기 전의 X와 Y의 초기값이 각각 300000과 600000이라고 가정하면 T1의 수행을 먼저 완료하고 T2의 수행을 완료하던지, T2의 수행을 먼저 완료하고 T1의 수행을 완료하던지 관계 없이 X의 최종값은 250000, Y의 최종값은 700000이 되어야 한다.

    - 오손 데이터 읽기: 완료되지 않은 트랜잭션이 갱신한 데이터 읽음

    트랜잭션 T1이 정미림의 잔액을 100000원 감소시킨 후에 트랜잭션 T2는 모든 계좌의 잔액의 평균값을 검색하였다. 그 이후에 T1이 어떤 이유로 철회되면 T1이 갱신한 정미림 계좌의 잔액은 원래 상태로 되돌아간다. 따라서 T2는 완료되지 않은 트랜잭션이 갱신한 데이터, 즉 틀린 데이터를 읽었다.

    - 반복할 수 없는 읽기: 한 트랜잭션이 동일한 데이터를 두 번 읽을 때 서로 다른 값을 읽음

    먼저 트랜잭션 T2는 모든 계좌의 잔액의 평균값을 검색하였다. 트랜잭션 T2가 완료되기 전에 트랜잭션 T1이 정미림의 잔액을 100000원 감소시키고 완료되었다. 트랜잭션 T2가 다시 모든 계좌의 잔액의 평균값을 검색하면 첫 번째 평균값과 다른 값을 보게 된다. 동일한 읽기 연산을 여러 번 수행할 때 매번 서로 다른 값을 보게 될 수 있다.

  • 항공기 예약 트랜잭션
    - 여러 여행사에서 동시에 고객들의 요청에 따라 동일한 날짜에 출발하는 항공기의 빈 좌석 유무 검사 가능
    - DBMS가 아무런 조치 취하지 않으면, 1개 남은 좌석에 두 명의 고객이 배정되는 결과 초래

로킹(locking)

: 동시에 수행되는 트랜잭션들의 동시성 제어를 위해 가장 널리 사용되는 기법

  • 로크(lock): 데이터베이스 내의 각 데이터 항목과 연관된 변수
  • 로크 테이블: 각 트랜잭션에 수행을 시작하여 데이터 항목을 접근할 때마다 요청한 로크에 관한 정보 유지
    - 독점 로크(X-lock): 트랜잭션에서 갱신 목적으로 데이터 항목 접근
    - 공유 로크(S-lock): 트랜잭션에서 읽을 목적으로 데이터 항목 접근
    - 해제: 트랜잭션이 데이터 항목 접근 끝냄

  • 2단계 로킹 프로토콜
    : 로크 요청, 로크 해제가 2단계로 구성
    로크 확장 단계 지난 후에 로크 수축 단계 들어감. 로크 하나라도 해제 시, 로크 수축 단계.
    - 로크 포인트: 한 트랜잭션에서 필요로 하는 모든 로크를 걸어놓은 시점
  1. 로크 확장 단계
    : 트랜잭션이 데이터 항목에 대해 새로운 로크를 요청 O. 보유 중인 로크 하나라도 해제 X.
  2. 로크 수축 단계
    : 보유 중인 로크 해제 O. 새로운 로크 요청 X.
    로크 조금씩 해제 / 트랜잭션 완료 시점에는 한꺼번에 해제 가능.(일반적으로 이 방법 사용)
  • 데드록(deadlock)
    : 두 개 이상의 트랜잭션들의 서로 상대방이 보유하고 있는 로크를 요쳥하면서 기다리고 있는 상태
    => 데드록 방지 기법, 데드록 탐지하고 희생자 선정하여 데드록 푸는 기법 사용

  1. T1이 X에 대해 독점 로크 요청하여 허가받음
  2. T2가 Y에 대해 독점 로크 요청하여 허가받음
  3. T1이 Y에 대해 공유 로크나 독점 로크 요청 시, 로크 해제 시까지 기다림
  4. T2가 X에 대해 공유 로크나 독점 로크 요청 시, 로크 해제 시까지 기다림
  • 다중 로크 단위(multiple granularity)
    : 한 트랜잭션에서 로크할 수 있는 데이터 항목이 두 가지 이상 존재
    * 로크 가능 단위: 데이터베이스, 릴레이션, 디스크 블록, 튜플
    - 트랜잭션에서 접근하는 튜플 수에 따라 자동으로 로크 단위 조정
    로크 단위 ⬇️, 로킹에 따른 오버헤드 ⬆️, 동시성 정도 ⬆️
    1. EMPLOYEE 릴레이션에 속하는 디스크 블록 b1에 다섯 개의 투플 t1, t2, t3, t4, t5가 있다고 가정하자. 또한 트랜잭션 T1은 이 중에서 투플 t1과 t4를 갱신하고, 트랜잭션 T2는 투플 t2를 검색한다고 가정하자. 만일 로크 단위가 투플이라면 두 트랜잭션이 접근하는 투플들이 서로 상이하므로 해당 투플에 로크를 걸고 두 트랜잭션이 동시에 수행될 수 있다.
  1. 트랜잭션 T1은 블록 단위, T2는 투플 단위로 로크를 하는 경우에, 먼저 T1이 블록 b1에 대해 독점 로크를 요청하여 허가를 받으면 이 블록에 들어 있는 투플 다섯 개에도 모두 독점 로크가 걸린다. 그 다음에 트랜잭션 T2가 투플 t2에 대해 공유 로크를 요청하면 트랜잭션 T1이 로크를 풀 때까지 기다려야 한다.
  • 팬텀 문제

    - 시간1: 트랜잭션 T1의 SELECT문 수행 시, 1번 부서에 근무하는 사원들의 이름 박영권, 김상원 검색
    - 시간2: 트랜잭션 T2의 INSERT문 수행 시, EMPLOYEE 릴레이션에 1번 부서에 근무하는 정희연 튜플 삽입
    - 시간3: 트랜잭션 T1의 두 번째 SELECT문 수행 시, 박영권, 김상원, 정희연 검색
    => 한 트랜잭션 T1에 속한 첫 번째 SELECT문과 두 번째 SELECT문의 수행 결과가 다르게 나타남

회복

  • 회복의 필요성
    - 트랜잭션 수행 도중 시스템 다운 시, 수행 효과가 디스크의 데이터베이스에 일부 반영되었을 수 있음
    => 어떻게 트랜잭션 수행을 취소하여 원자성 보장할 것인가?
    - 트랜잭션 완료 직후 시스템 다운 시, 모든 갱신 효과가 주기억장치로부터 디스크에 기록되지 않았을 수 있음
    => 어떻게 트랜잭션 수행 결과가 데이터베이스에 완전히 반영되도록 하여 지속성 보장할 것인가?
    - 디스크 헤드 등이 고장나서 디스크의 데이터베이스를 접근할 수 없다면 어떻게 할 것인가?

  • 회복: 여러 응용이 주기억 장치 버퍼 내의 동일한 데이터베이스 항목 갱신 후, 디스크에 기록함으로써 성능을 향상.
    - 재수행(REDO): 고장 발생 전, 트랜잭션이 완료 명령 수행했다면 회복 모듈은 이 트랜잭션의 갱신사항을 재수행하여 트랜잭션의 갱신이 지속성을 갖도록 함
    - 취소(UNDO): 고장 발생 전, 트랜잭션이 완료 명령 수행하지 못했다면 이 트랜잭션이 데이터베이스에 반영했을 가능성이 있는 갱신사항을 취소하여 원자성을 갖도록 함

  • 저장 장치 유형
    - 주기억장치: 휘발성. 시스템 다운 시 저장 내용 사라짐
    - 디스크: 비휘발성. 디스크 헤드 손상 입지 않는 한 시스템 다운 후에도 유지
    - 안전 저장 장치: 모든 유형의 고장을 견딜 수 있는 저장 장치.
    두 개 이상의 비휘발성 저장 장치가 동시에 고장날 가능성 매우 낮음. 비휘발성 저장 장치에 두 개 이상의 사본을 중복해서 저장하는 방식으로 구현.

  • 고장
    - 재해적 고장
    : 디스크가 손상을 입어 데이터베이스 읽을 수 없는 고장
    자기 테이프기반으로 회복
    - 비재해적 고장
    : 그 이외의 고장
    회복 알고리즘 적용으로 회복
    => 로그를 기반으로 한 즉시 갱신, 로그를 기반으로 한 자연 갱신, 그림자 페이징 등

로그 기반 즉시 갱신

  • 즉시 갱신: 갱신 사항이 주기억 장치 버퍼에 유지되다가 트랜잭션 완료 전이라도 디스크의 데이터베이스에 기록 가능 (완료된 트랜잭션 수행 결과 + 철회된 트랜잭션 수행 결과)

  • 로그: 트랜잭션의 원자성과 지속성 보장 위해 유지되는 특별한 파일
    - 로그 레코드: 데이터베이스의 항목에 영향을 미치는 모든 트랜잭션의 연산에 대해 기록.
    로그 순서 번호(LSN)로 식별.
    - 주기억 장치 내의 로그 버퍼에 로그 레코드 기록. 로그 버퍼 꽉 찰 때 디스크 기록
    - 데이터베이스 회복에 필수적. 안전 저장 장치에 저장.
    * 이중 로그: 로그를 두 개의 디스크에 중복 저장
    - 트랜잭션 ID: 각 로그 레코드가 어떤 트랜잭션에 속한 것인가를 식별.
    동일한 트랜잭션에 속하는 로그 레코드들은 연결 리스트로 유지.

  • 로그 레코드 유형
    - [Trans-ID, start]: 한 트랜잭션 생성 시 기록
    - [Trans-ID, X, old_value, new_value]: 주어진 Trans_ID를 갖는 트랜잭션이 데이터 항목 X를 이전값(old_value)에서 새값(new_value)로 수정했음을 기록
    - [Trans-ID, commit]: 주어진 Trans_ID를 갖는 트랜잭션이 데이터베이스에 대한 갱신을 모두 성공적으로 완료하였음을 기록
    - [Trans-ID, abort]: 주어진 Trans_ID를 갖는 트랜잭션이 철회되었음을 기록


    T1 다음에 T2 수행, 데이터베이스 항목 A, B, C, D, E의 초기값은 100, 300, 5, 60 80이라고 가정. 두 트랜잭션 수행 시, 표와 같은 로그 레코드 생성. 2번 로그 레코드는 트랜잭션 T1이 데이터베이스 항목 B를 이전값 300에서 400으로 갱신했음을 표현. 일단 이 로그 레코드가 디스크의 로그에 기록된 후에는 B가 새값으로 고쳐진 주기억 장치의 버퍼가 언제든지 디스크의 데이터베이스에 기록 가능.

  • 트랜잭션 완료점(Commit Point)
    : 한 트랜잭션이 데이터베이스 갱신 연산이 모두 끝나고 데이터베이스 갱신 사항이 로그에 기록되었을 때 도달.
    - 로그에 [Trans-ID, start], [Trans-ID, commit] 레코드 모두 존재하는 트랜잭션 재수행
    - 로그에 [Trans-ID, start]는 존재하지만, [Trans-ID, commit] 레코드 존재하지 않는 트랜잭션 취소

  • 로그 먼저 쓰기(WAL)
    : 로그 버퍼를 디스크에 기록 전에 시스템 다운 시, 휘발
    => 데이터베이스 버퍼보다 로그 버퍼를 먼저 디스크에 기록

체크포인트

: 회복 시 재수행할 트랜잭션의 수를 줄이기 위해 주기적으로 체크포인트 수행
체크포인트 시점: 주기억장치의 버퍼 내용이 디스크에 강제로 기록됨. => 디스크 상에서 로그와 데이터베이스 내용 일치
체크포인트 작업 종료 시, 로그에 [checkpoint] 로그 레코드 기록

  • 체크포인트를 할 때 수행되는 작업
    - 주기억 장치의 로그 버퍼를 디스크에 강제로 출력
    - 주기억 장치의 데이터베이스 버퍼를 디스크에 강제로 출력
    - [checkpoint] 로그 레코드를 로그 버퍼에 기록한 후 디스크에 강제로 출력
    - 체크포인트 시점에 수행 중이던 트랜잭션들의 ID도 [checkpoint] 로그 레코드에 함께 기록
    - 일시적으로 중지된 트랜잭션의 수행 재개

    • 체크포인트 X

      T0, T1, T3, T4, T5: 재수행 / T2, T6: 취소
    • 체크포인트 O

      T0, T1, T3: 무시 / T4, T5: 재수행 / T2, T6: 취소
    • 로그레코드
  • 데이터베이스 백업, 재해적 고장으로부터의 회복
    => 점진적 백업 바람직

profile
Hello, World!

0개의 댓글