본문 바로가기
Development/Database

RDBMS의 트랜잭션과 병행제어

by 메정 2021. 9. 23.

RDBMS의 트랜잭션

DBMS는 데이터베이스가 항상 정확하고 일관된 상태를 유지하도록 트랜잭션 단위로 일을 수행한다.
이를 통해 데이터베이스의 회복과 병행제어(동시성 제어)가 가능해져 일관성을 유지한다.

트랜잭션

하나의 작업을 수행하는데 필요한 데이터베이스의 연산들을 모아놓은 것으로, 데이터베이스의 논리적인 작업단위이다.

  • 업무 처리에 필요한 세부 프로그램 단위
  • 데이터베이스에 대한 연산(조회, 삽입, 삭제, 수정) SQL문들로 구성

데이터베이스에 장애 발생 시 데이터를 복구하는 작업 단위이다.

데이터베이스는 무결성, 일관성을 보장하기 위해 작업 수행에 필요한 연산들을 하나의 트랜잭션으로 정의, 관리한다.

ex. 계좌이체 트랜잭션

  1. 성호 계좌에서 5000원을 인출
  2. 은영 계좌에서 5000원을 입금
    → 계좌이체 전의 DB 상태 : 성호 잔액 10000원, 은영 잔액 0원
    → 계좌이체 후의 DB 상태 : 성호, 은영 잔액 각각 5000원

1.에서 인출하는 과정에서 데이터베이스가 UPDATE 되고,
2.에서 입금하는 과정에서 데이터베이스가 UPDATE 된다.

이렇게 UPDATE 연산이 수행되는 것들을 트랜잭션이라 하고, 이 트랜잭션은 SQL문으로 구성된다.

트랜잭션 특징 (ACID)

  1. 원자성(Atomicity) : 트랜잭션을 구성하는 연산들은 모두 정상적으로 실행되거나 실행되지 않아야 한다. //all-or-nothing
    • 트랜잭션 수행 중 장애 발생 시, 모두 취소시켜 DB를 트랜잭션 작업 전 상태로 돌려 원자성을 보장해야 함
  2. 일관성(Consistency) : 트랜잭션이 성공적으로 수행된 후 DB가 일관된 상태를 유지해야 한다.
    • 수행 전, 후 모두 일관된 상태여야 한다.
  3. 격리성(Isolation) : 현재 수행 중인 트랜잭션이 완료될 때까지 트랜잭션이 생성한 중간 연산 결과에 다른 트랜잭션들이 접근할 수 없어야 한다.
    • 갱신 중인 데이터에 중간 참조 불가
    • 여러 트랜잭션이 동시에 수행되더라도 각 트랜잭션은 독립적으로 수행될 수 있어야 함
  4. 지속성(Durability) : 트랜잭션이 성공적으로 완료된 후, DB의 반영된 결과는 손실될 수 없다.
    • 영구적으로 저장

트랜잭션의 특징들을 보장하기 위해 DBMS는 회복, 병행제어 기능을 제공한다.

원자성 ← 회복 기능 제공

일관성 ← 병행 제어 기능

격리성 ← 병행 제어 기능

지속성 ← 회복 기능

트랜잭션의 5가지 상태

트랜잭션 연산

  1. commit : 트랜잭션이 성공적으로 수행됨을 선언 (작업 완료)
    • 트랜잭션 연산 전, 후의 DB 상태를 일관된 상태로 유지
  2. rollback : 트랜잭션 수행을 실패함을 선언 (작업 취소)
    • 장애 발생 시, 트랜잭션 수행 전으로 되돌림

트랜잭션 상태

트랜잭션이 수행 시작되면, 활동 상태가 된다.
SQL문이 성공되면 부분 완료 상태가 되고, DB에 변경이 반영을 위해 commit 연산이 수행한다. (완료 상태)

SQL문이 실패하게되거나 성공했지만 장애가 발생하여 중단하게 된다면, 실패 상태가 되고, 트랜잭션 전 상태와 동일하게 DB에 일관성 유지를 위해 rollback 연산이 수행된다. (철회 상태)
완료 상태와 철회 상태는 트랜잭션이 종료된 것!

'장애'란

시스템이 제대로 동작되지 않는 상태로, 원인은 다양하다.

장애 유형

  1. 트랜잭션 장애 : 트랜잭션 수행 중 오류 발생 → 정상적으로 수행 불가한 상태
    • 원인) 논리적 오류, 잘못된 데이터 입력, 시스템 자원 과다 사용 요구 등
  2. 시스템 장애 : 하드웨어의 결함 → 정상적으로 수행 불가한 상태
    • 원인) 메인 메모리에 저장된 정보 손실, 교착 상태 발생 등
  3. 미디어 장애 : 디스크 장치의 결함 → 디스크에 저장된 DB의 일부 혹은 전체가 손상된 상태
    • 원인) 디스크 헤드의 손상이나 고장

//DB는 기본적으로 비휘발성 저장장치에 상주한다.

'회복'이란

장애 발생 시 발생 전 모순이 없고, 일관된 상태로 복구하는 것

DBMS의 회복관리자(recovery manager)가 장애 발생을 탐지하여 복구 기능을 제공하여 회복 작업이 진행

복구하는 동안 DB 접근이 불가하므로 빠르게 진행되어야 함

회복 기법

  1. 로그 회복 기법 : 로그 전체를 대상으로 회복 기법을 적용한다. (시간이 오래걸리고, 비효율적)
    1. 즉시 갱신 회복 기법 : 트랜잭션 수행 중에 데이터를 변경한 연산의 결과를 DB에 즉시 반영(commit)하고, 로그 파일에도 기록한다.
      • 트랜잭션 수행 → 로그파일에 기록 → DB 변경 연산 반영
      • 장애 발생 시 로그파일의 내용을 참조하여 장애 발생 시점에 따라 회복 연산(redo, undo) 실행하여 DB를 복구한다.
      • 트랜잭션 완료 후 장애 발생 (복사본을 덮음) → redo 연산
      • 트랜잭션 완료 전 장애 발생 → undo 연산
    2. 지연 갱신 회복 기법 : 트랜잭션 수행 중에 데이터 변경 연산의 결과를 DB에 즉시 반영하지 않고, 로그파일에만 기록한다.
      • 트랜잭션이 부분 완료된 후 모든 연산이 끝나면, 기록 내용을 DB에 한번에 반영(commit)
      • 트랜잭션 완료 후 장애 발생 → redo 연산
      • 트랜잭션 완료 전 장애 발생 → 로그 내용 무시하고 버림
  2. 검사 시점 회복 기법 (로그 이용) : 일정 시간 간격으로 검사시점(CheckPoint)를 생성하여 회복 작업의 범위를 지정
    • 일정 간격으로 검사 시점이 되면, 메인메모리에 있는 모든 로그 레코드를 로그 파일(Disk)에 저장 → 트랜잭션의 변경 내용을 DB에 반영 → 형식으로 로그파일 내 로그 레코드로 기록
    • 장애 발생 시 를 찾아 그 이후의 로그 기록까지만 회복 작업 수행
  3. 미디어 회복 기법 : 전체 DB의 내용을 일정 주기마다 다른 저장장치에 복사(dump), 복구 시 로그 내용을 토대로 redo 연산 수행하여 장애 발생 이전으로 복구
    • 비용이 많이 들고, CPU 낭비 발생한다.

병행 제어(Concurrenct Control)

DBMS는 병행 수행 기능을 통해 여러 개의 트랜잭션이 동시에 수행될 수 있도록 만들어준다.

병행 수행이란, 여러 트랜잭션들이 차례로 번갈아 수행되는 인터리빙(interleaving) 방식으로 진행되는 것이다. 여러 개의 트랜잭션이 동시에 수행되어 같은 데이터에 접근할 때 연산을 수행하는 경우 데이터의 모순, 갱신 분실, 연쇄 복귀 등의 문제가 생길 수 있다.

병행 제어(동시성 제어)는 연산을 수행해도 문제가 발생하지 않고 정확한 결과를 얻도록 트랜잭션의 수행을 제어하는 것이다.

병행 제어 기법

1. 로킹(Locking)

대표적인 병행 제어 기법

병행 수행 도중 하나의 트랜잭션이 사용하는 데이터에 자물쇠를 걸어 다른 트랜잭션이 접근할 수 없게 만들어 트랜잭션을 독점해서 사용하도록 하는 방법

  • lock 명령 : 트랜잭션이 사용할 데이터에 대한 독점권을 획득
  • unlock 명령 : 트랜잭션이 데이터에 대한 독점권을 반납

→ 상호 배제(mutual exclusion)하여 직렬 가능성을 보장하여 데이터에 독점적으로 접근하도록 함

lock 연산을 실행하는 대상 데이터의 크기(로킹 단위) : DB, 속성, 튜플 등 다양한 크기로 지정 가능

  • 로킹 단위가 클수록 병행성이 낮아 제어가 쉬움
  • 작을수록 병행성이 높아 제어가 어려움

→ 시스템에 따라 적절한 로킹 단위를 선택할 수 있어야 함.

병행 수행에서 일어나는 위험성을 방지하지만, 하나의 데이터를 공유하는 다른 트랜잭션의 연산을 지연시키게 됨. 필요한 부분만 lock을 설정하는 것이 바람직함

ex. 2개의 트랜잭션이 동일한 데이터에게 'read연산 → 트랜잭션 연산 → 해당 데이터에게 write로 갱신'할 경우, 모순이 발생할 수 있음!

먼저 연산을 수행하는 트랜잭션이 read와 write 모두 lock을 거는 것이 바람직

ex. 2개의 트랜잭션 모두 데이터를 읽기만 하는 read 연산이 수행되면, 한 트랜잭션이 실행될 때 다른 트랜잭션도 데이터에 접근해서 연산을 수행해도 문제가 되지 않음(데이터를 변경하지 않으므로)

이런 경우에는 write는 허용하지 않고, read는 허용하도록 설정하여 성능을 높일 수 있음

용도에 따라 공유lock(Shared Lock), 전용lock(Exclusive Lock)으로 구분할 수 있음

  • 공유lock(Shared Lock) : lock을 설정한 데이터에 대한 read만 허용, write는 불허
    • 사용권을 여러 트랜잭션이 함께 가질 수 있음 (SELECT는 되고, UPDATE, DELETE는 불가)
  • 전용lock(Exclusive Lock) : lock을 설정한 데이터에 대해 read, write 불허
    • 사용권을 한 트랜잭션이 독점할 수 있음

2. 2단계 로킹 규약

lock과 unlock 연산의 수행 시점에 대해 새로운 규약을 추가한 것

  • 확장 단계 : 트랜잭션이 lock 연산만 수행 가능, unlock 연산은 수행할 수 없는 단계
  • 축소 단계 : 트랜잭션이 unlock 연산만 수행 가능, lock 연산은 수행할 수 없는 단계

직렬 가능성을 보장해주지만, 교착 상태(Deadlock)이 발생할 가능성 있음

//교착상태 : 상대가 독점하는 데이터에 unlock 연산이 실행되길 기다리면서 트랜잭션 수행 대기

→ unlock 연산이 실행되기 전에 필요한 모든 lock연산이 수행되어야 함

3. 타임 스탬프 순서 기법

시스템에 들어오는 트랜잭션의 순서대로 고유번호인 타임 스탬프를 부여 → 타임 스탬프의 순서에 따라 데이터에 접근하여 실행하는 기법

타임 스탬프 기법은 정해진 순서에 따라 실행되므로 교착상태가 발생하지 않음.

참고자료

14. 데이터베이스의 회복(Recovery)과 병행제어
책 | 데이터베이스개론 2판, 한빛아카데미, 2019.8.3

'Development > Database' 카테고리의 다른 글

[lock]MySQL user-level lock vs Redisson  (0) 2021.11.23
MySQL DB log 보기  (0) 2021.11.23
MySQL Connection Pool 이란  (0) 2021.11.23

댓글