MVCC(Multi-Version Concurrency Control, 다중 버전 동시성 제어)

다중 버전 동시성 제어(MVCC, Multi-Version Concurrency Control)는 데이터베이스 시스템에서 동시성을 관리하는 기법으로, 트랜잭션이 동시에 실행될 때 읽기 작업과 쓰기 작업이 충돌하지 않도록 여러 개의 데이터 버전을 유지하는 방식입니다.

🔹 MVCC의 주요 개념

  1. 다중 버전 유지
    • 하나의 데이터에 대해 여러 버전의 스냅샷을 저장하여 트랜잭션이 특정 시점의 데이터를 볼 수 있도록 함
    • 새로운 트랜잭션이 시작되면 최신 데이터가 아닌, 트랜잭션이 시작될 당시의 데이터 버전을 읽음 (스냅샷 읽기)
  2. 잠금(Locking) 없이 동시성 보장
    • 일반적으로 READ 작업에서 잠금을 걸지 않음 → 다른 트랜잭션이 동시에 데이터를 수정할 수 있음
    • 쓰기 작업은 기존 데이터를 삭제하지 않고 새로운 버전을 생성하여 충돌을 방지함
  3. 트랜잭션 격리 수준과 MVCC
    • READ COMMITTED: 각 쿼리는 가장 최근에 커밋된 데이터를 읽음
    • REPEATABLE READ: 트랜잭션이 시작될 당시의 데이터를 유지하며 읽음
    • SERIALIZABLE: 모든 트랜잭션이 순차적으로 실행된 것처럼 보이도록 동작함
  4. Garbage Collection(불필요한 버전 정리)
    • 오래된 데이터 버전이 계속 남아있으면 스토리지 낭비가 발생할 수 있음
    • 일정 시간이 지나거나 더 이상 참조되지 않는 데이터 버전은 삭제됨

🔹 MVCC의 장점과 단점

장점

  • 읽기 작업과 쓰기 작업이 충돌하지 않음 → 높은 동시성 제공
  • 대부분의 읽기 작업에서 잠금을 사용하지 않아 성능이 향상됨
  • 트랜잭션 격리 수준을 높여도 성능 저하가 적음

단점

  • 여러 버전의 데이터를 유지해야 하므로 저장 공간이 많이 필요함
  • 불필요한 데이터 버전을 정리하는 추가적인 관리 작업(Garbage Collection)이 필요함

🔹 MVCC를 사용하는 대표적인 DBMS

  • PostgreSQL
  • MySQL (InnoDB 엔진)
  • Oracle (UNDO 기반)
  • Microsoft SQL Server (SNAPSHOT ISOLATION)

MVCC는 트랜잭션이 많은 환경에서 높은 동시성과 성능을 제공하는 중요한 기법이며, 대부분의 현대적인 데이터베이스에서 사용되고 있습니다.

MVCC 사용 예제

예제 1: PostgreSQL에서 MVCC 동작 확인

PostgreSQL에서는 MVCC를 활용하여 트랜잭션이 서로 영향을 주지 않고 실행될 수 있습니다.

1️⃣ 트랜잭션 1에서 데이터 조회
BEGIN TRANSACTION;
SELECT * FROM accounts WHERE id = 1;

accounts 테이블에서 id = 1인 계정 정보를 조회

  • 현재 트랜잭션이 시작될 당시의 스냅샷을 읽음
2️⃣ 트랜잭션 2에서 데이터 수정
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance + 100 WHERE id = 1;
COMMIT;
  • id = 1 계좌의 balance를 100 증가시킴
  • COMMIT하면 다른 트랜잭션에서는 변경된 데이터를 볼 수 있음
3️⃣ 트랜잭션 1에서 다시 데이터 조회
SELECT * FROM accounts WHERE id = 1;
  • 여전히 처음 조회했던 값이 유지됨 (스냅샷 읽기)
  • 트랜잭션 1이 종료되기 전까지는 트랜잭션 2의 변경 사항을 볼 수 없음
4️⃣ 트랜잭션 1 종료 후 다시 조회
COMMIT;
SELECT * FROM accounts WHERE id = 1;
  • 이제 최신 변경 사항을 반영한 데이터를 볼 수 있음

예제 2: MySQL InnoDB에서 MVCC 적용

MySQL의 InnoDB 엔진도 MVCC를 지원하며, 트랜잭션 격리 수준에 따라 동작이 달라짐

1️⃣ 트랜잭션 A에서 데이터 조회
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT * FROM orders WHERE order_id = 10;
  • REPEATABLE READ에서는 트랜잭션이 시작된 시점의 데이터를 계속 읽음
2️⃣ 트랜잭션 B에서 데이터 수정
START TRANSACTION;
UPDATE orders SET status = 'shipped' WHERE order_id = 10;
COMMIT;
  • orders 테이블의 order_id = 10 상태를 'shipped'로 변경
3️⃣ 트랜잭션 A에서 다시 조회
SELECT * FROM orders WHERE order_id = 10;
  • 변경 사항을 볼 수 없음 → 트랜잭션이 시작될 때의 스냅샷을 계속 유지
4️⃣ 트랜잭션 A가 종료된 후 다시 조회
COMMIT;
SELECT * FROM orders WHERE order_id = 10;
  • 이제 변경된 status = 'shipped' 데이터를 확인할 수 있음

MVCC의 활용 사례

온라인 뱅킹 시스템

  • 계좌 잔액을 조회할 때, 다른 사용자가 이체하는 동안에도 이전 상태를 유지하여 읽을 수 있음
  • 동시 출금 요청이 들어와도 충돌을 최소화함

전자상거래 시스템

  • 사용자가 상품 목록을 조회할 때, 다른 사용자가 가격을 변경해도 기존 가격을 유지할 수 있음
  • 트랜잭션을 롤백하더라도 기존 데이터를 안전하게 보호할 수 있음

분산 데이터베이스 및 클라우드 시스템

  • Amazon Aurora, Google Spanner 등에서 MVCC를 활용하여 읽기 성능을 높이고 동시성을 보장함
  • 데이터 일관성을 유지하면서도 높은 처리량을 제공

MVCC는 데이터베이스 성능을 향상시키면서도 데이터 정합성을 보장하는 중요한 기법이며, 트랜잭션이 많은 환경에서 매우 유용하게 활용됩니다.

Leave a Comment