[CUBRID] 2PL, MVCC, VACUUM

2024. 8. 25. 23:01·DBMS/CUBRID

2PL

  • 다수의 트랜잭션이 동시에 실행될 때, lock이 가능한 단계와 unlock만 가능한 단계를 구분하여 동시성을 제어하는 방법
  • 확장단계(Growing Phase): 트랜잭션은 lock 연산만 실행 가능, unlock 연산 불가
  • 축소단계(Shrinking Phase): 트랜잭션은 unlock 연산만 실행 가능, lock 연산 불가
  • 트랜잭션 실행 단계
    • 1단계: 트랜잭션이 필요로 하는 lock 권한들을 얻음
    • 2단계: 트랜잭션이 소유한 lock을 해제, 이때 새로운 lock을 요청할 수 없음

 

2PL 특징

  • 트랜잭션이 같은 데이터에 동시에 접근하는 것을 차단하여 직렬화(serializability)를 보장
  • 획득하려는 lock을 다른 트랜잭션이 먼저 lock을 획득하고 있는 경우 lock이 해체될 때까지 대기
  • DB 일관성이 높은 수준으로 보장됨
  • deadlock이 발생할 가능성이 있음

 

2PL 동작 방식

2개의 트랜잭션이 동시에 수행되는 경우

  • X를 갱신하는 Tx1이 실행되는 도중, X를 조회하는 Tx2이 실행됨
  • Tx2가 S-lock(X)을 획득하기 위해서는, X-lock(X)이 해제될 때까지 대기해야 함
  • Tx1에서 X-lock(X)을 해제되면, Tx2은 S-lock(X)을 획득하고 트랜잭션 수행
lock 상태  Tx1  Tx2  lock 상태
획득 X-lock(X)    
  read X S-lock(X) 대기
  update X    
해제 X-lock(X)    
    S-lock(X) 획득
    read X  
    S-lock(X) 해제

 

MVCC

  • 트랜잭션을 수행할 때 마다 객체에 대해 여러 버전을 생성해서, 기존의 데이터와 변경된 데이터를 동시에 유지하는 방법
  • 생성되는 버전인 MVCCID는 고유 식별자
  • 즉 MVCC에서는 하나의 데이터에 대해 여러 버전의 데이터가 존재하고, 사용자는 마지막 버전의 데이터를 읽음

 

MVCC 특징

  • 다른 트랜잭션이 수정 중인 객체를 읽는 것을 허용함
  • 2PL 방식과 비교했을 때, read/write 동시성을 허용하기 때문에 빠른 동작 가능
  • 새로운 버전의 데이터를 지속적으로 만들기 때문에, 사용하지 않는 데이터를 정리하는 시스템이 필요 → VACUUM

 

MVCC 구현 방식

  • snapshot을 통해 각각의 MVCCID 마다 데이터의 변경사항을 저장
    • snapshot: 이전 버전의 데이터와 비교해서 변경된 내용을 기록
  • 가장 최근에 commit된 MVCCID에서 1을 증가시킨 값을 새로운 MVCCID로 할당
  • 최근 commit된 MVCCID와 snapshot을 확인하기 위해 활성 트랜잭션 목록을 유지
  • 레코드를 insert한 트랜잭션과 delete한 트랜잭션을 구분하기 위해, insert MVCCID와 delete MVCCID를 기록함
  • MVCC flag로 레코드의 상태를 판별
    • 1: insert
    • 3: delete
    • 5: update
    • 7: update → delete

 

MVCC 동작 방식

새로운 레코드를 insert하는 경우

  • a=1를 테이블에 insert
insert into test_tbl values(1);

 

  • 새로운 버전을 생성하고 MVCCID를 insert_id로 설정
  • 해당 트랜잭션이 commit 될 때까지 다른 트랜잭션은 추가된 레코드를 읽을 수 없음

 

레코드를 update하는 경우

  • a=2 → a=3로 update
update test_tbl set a=3 where a=2;

 

  • 레코드를 업데이트하고 이전 값을 log에 저장
  • 해당 레코드의 MVCCID를 새로운 버전으로 변경하고, prev_version을 설정

 

  • 데이터가 변경되고 나서 이전의 데이터는 log에 저장됨

 

레코드를 delete하는 경우

  • a=1인 레코드를 delete
delete test_tbl where a=1;

 

  • 기존의 버전을 삭제하지 않고, MVCCID를 delete_mvccid로 설정
  • 이는 타 트랜잭션이 해당 레코드를 식별 가능하게 함

 

MVCC에서 데이터를 읽는 방식

  • 자신의 MVCCID보다 상위 버전을 읽을 수 없음
  • 생성된 MVCCID가 다음과 같을 때, MCVVID마다 읽는 데이터는 다음과 같음

  • 현재 MVCCID가 188일 때 
    a
    1
  • 현재 MVCCID가 189일 때, log에 저장된 값인 2를 읽어옴
    a
    1
    2
  • 현재 MVCCID가 190일 때
    a
    1
    3
  • 현재 MVCCID가 191일 때
    a
    1

 

VACUUM

  • MVCC에서 기존 버전을 유지하면서 새 버전을 지속적으로 생성하면, 데이터베이스 크기가 무한으로 증가하는 문제가 발생
  • 사용하지 않는 이전 데이터를 제거하기 위한 시스템이 필요
  • 각각의 행 버전은 다음의 단계를 거침
    1. 레코드를 insert하는 트랜잭션을 수행 시 commit 되지 않았으면, 해당 트랜잭션만 레코드를 조회할 수 있음
    2. (1)의 트랜잭션이 commit 되는 시점 이전의 트랜잭션은 해당 레코드를 조회할 수 없음, 이후 시점의 트랜잭션은 조회 가능
    3. 레코드를 delete하는 트랜잭션을 수행 시 commit 되지 않았으면, 다른 트랜잭션은 해당 레코드를 조회 가능, delete 트랜잭션은 레코드를 볼 수 없음
    4. (3)의 트랜잭션이 commit 되는 시점 이전의 트랜잭션은 해당 레코드를 볼 수 있고, 이후 트랜잭션은 볼 수 없음
    5. 모든 활성화 트랜잭션이 완료될 때까지 볼 수 없음
    6. 데이터 베이스에서 제거
  • vacuum은 활성화 되지 않은 삭제된 레코드의 버전을 제거하기 위해 가져옴

 

VACUUM 원칙

  • 정확하고 안전해야함
    • Active한 데이터를 제거하면 안되고, 더 이상 사용하지 않는 데이터를 놓치면 안됨
  • 신중해야함
    • 정리 프로세스가 데이터베이스의 내용을 변경하므로, 실제 트랜잭션 활동에 간섭을 최소화 해야함
  • 빠르고 효율적이어야 함

 

VACUUM 구현 방식

복구 로깅

  • 복구 로깅에는 힙 및 인덱스 변경에 대한 복구 데이터 주소를 유지 → 데이터베이스를 스캔하지 않고 VACUUM이 대상으로 바로 이동 가능
  • log 데이터의 처리는 활성 worker의 작업에 간섭을 일으키지 않음
  • VACUUM은 처리할 로그 항목을 MVCCID를 기반으로 결정
  • 각 트랜잭션은 활성화된 가장 오래된 MVCCID를 유지, 해당 MVCCID보다 낮은 버전은 삭제할 수 있음

 

병렬 수행

  • 로그 데이터를 고정 크기 블록으로 분할하고, 각 블록마다 하나의 vacuum 작업을 생성하여 병렬 처리
  • vacuum 작업은 로그 블록에 있는 관련 로그 항목을 기반으로 데이터 공간을 회수하는 VACUUM Worker 들에 의해 선택
  • 로그 블록의 추적 및 vacuum 작업의 생성은 VACUUM Master가 수행

 

VACUUM 데이터

  • 로그 블록에서 수집된 데이터는 vacuum 데이터 파일에 저장 → vacuum 데이터 파일은 VACUUM 작업을 수행할 때까지 유지됨
  • 수집된 로그 블록 데이터는 ‘래치-프리(latch-free) 버퍼 → vacuum 데이터 파일’을 거쳐 저장
    • 래치-프리(latch-free) 버퍼는 vacuum 시스템에서 작업 중인 스레드(로그 블록 및 수집 데이터 생성)들의 간섭을 피하기 위해 사용
    • VACUUM Master가 주기적으로 버퍼에 있는 모든 내용을 vacuum 데이터로 저장

'DBMS > CUBRID' 카테고리의 다른 글

[CUBRID] 백업과 복구의 이해  (0) 2024.08.26
[CUBRID] VACUUM 테스트  (0) 2024.08.25
[CUBRID] Lock 관련 파라미터  (0) 2024.08.25
[CUBRID] Lock 발생시킨 후 잠금 상태 확인  (0) 2024.08.25
[CUBRID] 잠금과 교착 상태  (1) 2024.06.01
'DBMS/CUBRID' 카테고리의 다른 글
  • [CUBRID] 백업과 복구의 이해
  • [CUBRID] VACUUM 테스트
  • [CUBRID] Lock 관련 파라미터
  • [CUBRID] Lock 발생시킨 후 잠금 상태 확인
Doodo
Doodo
  • Doodo
    Doodo
    Doodo
  • 전체
    오늘
    어제
    • 분류 전체보기 (192)
      • CS (17)
        • Network (11)
        • Database (6)
      • Language (19)
        • Python (11)
        • SQL (6)
        • R (2)
      • Linux (17)
      • DevOps (35)
        • Git (7)
        • Docker (8)
        • Kubernetes (9)
        • GCP (4)
        • AWS (7)
      • Data Engineering (50)
        • 책 리뷰 (14)
        • Airflow (35)
        • Redis (1)
      • DBMS (21)
        • CUBRID (21)
      • ML & DL (2)
      • 코딩테스트 (24)
      • 프로젝트 (7)
        • 서울시 대기현황 데이터 적재 프로젝트 (4)
        • CryptoStream (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Doodo
[CUBRID] 2PL, MVCC, VACUUM
상단으로

티스토리툴바