[DB] 트랜잭션 관리 전략

Manx·2023년 5월 22일
0

DBMS

목록 보기
2/8
  • DBMS는 데이터를 고정 길이의 페이지로 저장하며, 디스크에서 읽거나 쓸 때에 페이지 단위로 입출력이 이루어진다.
  • 페이지들을 관리하는 모듈을 페이지 버퍼 관리자 or 버퍼 관리자 라고 한다.
  • 질의 처리기 ( Query Processor ) 와 저장 시스템 ( Storage System )으로 나눠볼 수 있다.
  • Ex. MySQL → InnoDB, MyISAM


UNDO

  • 수정된 페이지들이 버퍼 관리자의 버퍼 교체 알고리즘에 따라 디스크에 출력될 수 있다.
  • 완료되지 않은 트랜잭션이 수정한 페이지들도 디스크에 출력될 수 있으므로, 문제가 발생했을 때 이 트랜잭션이 변경한 페이지들은 원상복구 되어야 한다.
  • 이를 UNDO 라고 한다.
  • 만약 버퍼 관리자가 트랜잭션 종료 전에는 어떤 경우에도 디스크에 쓰지 않는다면, UNDO 오퍼레이션은 메모리 버퍼에 대해서만 이루어 지면 된다.
    • 매력적이긴 하나, 매우 큰 크기의 메모리 버퍼가 필요하다.

수정된 페이지를 디스크에 쓰는 시점에 대한 정책

  • STEAL : 수정된 페이지를 언제든지 디스크에 쓸 수 있는 정책
  • -STEAL : 수정된 페이지들을 최소한 트랜잭션 종료 시점 (EOT, End Of Transaction)까지는 버퍼에 유지하는 정책

💡 STEAL 정책은 필연적으로 UNDO 로깅과 복구를 수반하는데, 거의 모든 DBMS가 채택하는 버퍼 관리 정책이다.


REDO

  • 커밋한 트랜잭션의 수정은 어떤 경우에도 유지되어야 한다.

수정된 페이지를 디스크에 쓰는 시점에 대한 정책

  • FORCE : 수정했던 모든 페이지를 트랜잭션 커밋 시점에 디스크에 반영
    • 이미 디스크에 써져 있기 때문에 REDO 오퍼레이션이 필요 없다.
  • -FORCE : 수정했던 페이지를 트랜잭션 커밋 시점에 디스크에 반영하지 않는 정책
    • 커밋한 내용이 디스크 상에 없을 수 있어 REDO가 필요하다.
    • 그렇다면 언제 디스크에 반영될까 ? ( 하단에서 설명 )

💡 거의 모든 DBMS가 -FORCE 정책을 사용한다.


트랜잭션 관리

UNDO와 REDO를 위해 가장 널리 쓰이는 구조는 로그(log)이다.

로그

  • 로그 레코드의 연속이며 데이터베이스의 모든 갱신 작업을 기록한다.
  • 로그는 덧붙이는 방식으로 기록되며, 각 로그 레코드는 고유 식별자를 가진다.
  • 로그 레코드의 식별자를 LSN(Log Sequence Number) or LSA ( LOg Sequence Address )라고 부른다.

물리적인 상태 로깅

  • DBMS에서 가장 널리 쓰이는 기본저긴 로깅 방법
  • 로그 레코드는 갱신 이전 이미지와 이후 이미지를 모두 다 가지고 있다.
  • UNDO : 이전 이미지로 현재 이미지 대체
  • REDO : 이후 이미지를 반영

물리적인 전이 로깅 ( physical transition loggin )

  • 이전 및 이후 이미지를 모두 기록하기 보다는 XOR 차이점을 기록하는 방식이다.

논리적인 전이 로깅 ( logical transition loggin )

  • 오퍼레이션 로깅이라고도 불린다.
  • 결과 값을 기록하는 방식이 아닌, 어떤 일을 했었는가를 기록하는 방식.
  • a = a + 1 연산을 했을 때, 0과 1을 로깅하는 것이 아닌 연산 자체를 기록.
  • REDO : 연산 재수
  • UNDO : 역 오퍼레이션 수행
  • 로그 레코드의 크기를 크게 줄여준다는 장점이 있다. 물리적으로 복구하기 쉽지 않은 자료 구조에 대한 로깅을 쉽게 해준다.
    • B+-tree, B-tree는 merge를 통해 레코드의 위치가 계속 변경되지 때문에 로깅 시점과 복구 시점의 데이터 물리적 위치가 같다는 점이 보장되지 않기 때문에, 물리적인 로그를 통해서 복구하기가 쉽지 않지만, 논리적인 로그를 통해서 보다 쉽게 복구할 수 있다.

논리적 로깅의 멱등성

  • UNDO, REDO는 멱등성을 보장해야 한다.
  • a++ 연산을 여러 번 반복해서 복구하면 멱등성을 위배할 수 있다.
  • 이를 해결하기 위한 방법은 다음과 같다.

로그 작성 과정

  • 업데이트가 데이터베이스에 써지기 전에 먼저 UNDO 정보가 로그에 써져야 한다.
  • 이 원칙을 WAL(Write Ahead Loggin)이라고 한다.
  • 트랜잭션이 정상적으로 종료 처리 되기 위해서는 먼저 REDO 정보가 로그에 써져야 한다.
  • REDo를 할 수 있기 위해서는 REDO로그가 적어도 커밋 시점에는 써져야 한다.

로그 데이터 작성 Cost

  • 로그 레코드가 손실되는 경우가 발생하면 DB가 완전히 복구될 수 없기 때문에 안전하게 쓰는 것이 필요하다.
  • 최대한 안전하게 로그를 쓰기 위해 write 함수 호출 외에 fsync함수를 호출한다.
  • fsync 함수 호출은 매우 느린 연산이고, 해당 트랜잭션의 로그가 로그 파일에 써져야 하기 때문에 커밋을 하려는 트랜잭션은 fsunc 함수 호출 종료를 대기해야 한다.
  • 따라서 매우 성능이 낮다.

성능을 높이는 방법

  1. 그룹 커밋 ( group commit )
    1. 각각의 트랜잭션의 커밋 요구를 개별적으로 처리하는 것이 아닌 모아서 한꺼번에 처리하는 방식
    2. 요청을 한 번에 처리하게 되면 디스크 출력 횟수를 줄일 수 있으므로 성능을 높일 수 있따.

커밋 성능 극대화를 위해 지속성을 일부 포기하는 방식도 있다.



출처

https://d2.naver.com/helloworld/407507

profile
백엔드 개발자

0개의 댓글