MVCC
MVCC (Multi-Version Concurrency Control)
- MVCC(Multi-Version Concurrency Control) 는 데이터베이스에서 동시성을 높이고 트랜잭션 간의 충돌을 줄이기 위해 사용되는 기법.
- PostgreSQL과 MySQL(InnoDB)은 각각 다른 방식으로 MVCC를 구현하여, 트랜잭션이 락을 걸지 않고도 데이터를 안전하게 읽을 수 있도록 보장한다.
PostgreSQL의 MVCC (Tuple Versioning)
PostgreSQL은 Tuple Versioning 방식으로 MVCC를 구현.
PostgreSQL MVCC 동작 방식
- 트랜잭션이 시작될 때, 특정 시점(Snapshot)의 데이터를 읽음
- 다른 트랜잭션이 데이터를 변경하더라도, 현재 트랜잭션에서는 변경 전 데이터가 유지됨.
- 각 행(Row, Tuple)에
xmin
,xmax
필드(트랜잭션 ID)를 유지xmin
: 해당 데이터를 생성한 트랜잭션 IDxmax
: 해당 데이터를 삭제 또는 수정한 트랜잭션 ID
- DELETE 및 UPDATE 시, 기존 데이터를 즉시 삭제하지 않고 새로운 버전을 생성
- UPDATE는 내부적으로 DELETE + INSERT 방식으로 처리됨.
- 따라서 기존 데이터는 유지되며, 새로운 트랜잭션은 가장 최신 데이터를 확인함.
- 커밋되지 않은 트랜잭션이 생성한 데이터를 다른 트랜잭션에서는 볼 수 없음
SELECT
시 해당 트랜잭션의 Snapshot을 기준으로 유효한 튜플만 조회함.
- 오래된 데이터(불필요한 튜플)는 Autovacuum 프로세스를 통해 정리됨
- PostgreSQL에서는 오래된 튜플(더 이상 사용되지 않는 데이터)을
Autovacuum
이 주기적으로 정리하여 스토리지를 최적화함.
- PostgreSQL에서는 오래된 튜플(더 이상 사용되지 않는 데이터)을
PostgreSQL MVCC 예제
-- 트랜잭션 1 시작
BEGIN;
UPDATE users SET name = 'Alice' WHERE id = 1; -- 기존 행을 삭제하고 새 행을 삽입
-- 트랜잭션이 아직 커밋되지 않음
-- 트랜잭션 2에서 동일한 데이터를 조회
SELECT * FROM users WHERE id = 1;
-- 트랜잭션 1이 커밋되지 않았다면 기존 데이터가 유지됨
- PostgreSQL에서는 트랜잭션 ID(
xmin
,xmax
)를 기반으로 다른 트랜잭션에서 볼 수 있는 데이터를 결정. - 즉, 트랜잭션이 변경한 데이터를 다른 트랜잭션에서 즉시 볼 수 없으며, 변경 전 데이터를 유지하는 방식.
MySQL(InnoDB)의 MVCC (Undo Log 기반)
MySQL의 InnoDB는 Undo Log 기반으로 MVCC를 구현.
MySQL MVCC 동작 방식
- 트랜잭션이 시작될 때, 특정 시점(Snapshot)의 데이터를 읽음
- 다른 트랜잭션이 데이터를 변경하더라도, 현재 트랜잭션에서는 변경 전 데이터를 유지.
- Undo Log를 사용하여 과거 데이터를 관리
- 변경 전 데이터를 Undo Log에 저장해 두고, 특정 트랜잭션이 이전 버전 데이터를 필요로 하면 Undo Log를 조회하여 제공.
- DELETE 및 UPDATE 시, 기존 데이터를 즉시 삭제하지 않고 Undo Log에 저장
- UPDATE는 내부적으로 DELETE + INSERT 방식으로 처리되며, Undo Log를 활용하여 과거 버전을 유지.
- SELECT 시 Undo Log를 참조하여 트랜잭션 격리 수준을 유지
Read Committed
에서는 커밋된 최신 데이터를 읽고,→Repeatable Read
에서는 트랜잭션이 시작될 당시의 데이터를 유지함.
- Purge Thread가 오래된 Undo Log를 정리
- MySQL은 PostgreSQL의 Autovacuum과 달리, Purge Thread가 불필요한 Undo Log를 제거함.
MySQL MVCC 예제
-- 트랜잭션 1 시작
START TRANSACTION;
UPDATE users SET name = 'Bob' WHERE id = 1; -- 기존 데이터를 변경
-- 트랜잭션이 아직 커밋되지 않음
-- 트랜잭션 2에서 동일한 데이터를 조회
SELECT * FROM users WHERE id = 1;
-- MySQL의 MVCC는 Undo Log를 활용하여 변경 전 데이터를 제공
- MySQL에서는 Undo Log를 사용하여 트랜잭션이 변경한 데이터를 다른 트랜잭션에서 즉시 볼 수 없도록 보장.
- 즉, Undo Log를 조회하여 “트랜잭션 시작 시점의 데이터”를 유지하는 방식.
PostgreSQL vs MySQL(InnoDB) MVCC 비교
특징 | PostgreSQL | MySQL (InnoDB) |
---|---|---|
MVCC 방식 | Tuple Versioning (각 행에 여러 버전 저장) | Undo Log 기반 (과거 데이터를 Undo Log에 저장) |
데이터 삭제 방식 | DELETE 및 UPDATE 시, 기존 데이터를 유지하고 새 버전 생성 | Undo Log에 기존 데이터 저장 후 삭제 |
Garbage Collection | Autovacuum 프로세스가 오래된 데이터를 정리 | Purge Thread가 불필요한 Undo Log 정리 |
트랜잭션 시작 시 데이터 읽기 | 트랜잭션 ID(xmin , xmax )를 기반으로 유효한 데이터 결정 |
Undo Log를 참조하여 트랜잭션 시작 당시 데이터를 유지 |
SELECT 락 사용 여부 | SELECT 시 락을 걸지 않음 | SELECT 시 락을 걸지 않음 |
Read Committed 격리 수준 | 최신 커밋된 데이터만 읽음 | 최신 커밋된 데이터만 읽음 |
Repeatable Read 격리 수준 | 트랜잭션 시작 시점의 데이터를 유지 | Undo Log를 사용하여 트랜잭션 시작 시점의 데이터를 제공 |
정리
- PostgreSQL의 MVCC는 Tuple Versioning 방식을 사용
- 각 행(Row)에 트랜잭션 ID(
xmin
,xmax
)를 저장하여 버전 관리 - Autovacuum이 오래된 데이터(Tuple)를 정리
- 장점: Undo Log가 필요 없고, 읽기 트랜잭션이 가볍다.
- 단점: 업데이트가 많으면 오래된 Tuple이 쌓여 성능 저하 가능.
- 각 행(Row)에 트랜잭션 ID(
- MySQL InnoDB의 MVCC는 Undo Log 기반으로 동작
- 변경 전 데이터를 Undo Log에 저장하여 과거 데이터를 제공
- Purge Thread가 불필요한 Undo Log를 제거
- 장점: Undo Log를 통해 과거 데이터를 관리하여 불필요한 데이터 유지 최소화.
- 단점: Undo Log가 쌓이면 Purge Thread 부담 증가, 성능 저하 가능.
Comments