Notice
Recent Posts
Recent Comments
Link
변수의 기록
(데이터베이스) MVCC와 Isolation Level – Oracle 예제 본문
MVCC와 Isolation Level – Oracle 예제
1. MVCC란?
**MVCC (다중 버전 동시성 제어)**는 동시성을 높이기 위해 트랜잭션마다 **자신만의 일관된 데이터 시점(snapshot)**을 제공하는 방식이다.
MVCC를 사용하는 데이터베이스는 읽기와 쓰기 간의 충돌(Blocking)을 제거하고, 성능과 일관성을 동시에 추구한다.
2. MVCC의 핵심 개념
구분 | 설명 |
읽기(read) | 특정 트랜잭션이 시작될 때의 "시점" 기준으로 commit된 데이터만 읽는다 |
쓰기(write) | 기존 데이터를 직접 수정하지 않고, 새로운 버전의 데이터를 생성 |
커밋 후 노출 | 다른 트랜잭션은 오직 commit된 버전만 읽을 수 있다 |
비차단 (non-blocking) | 읽기와 쓰기 작업은 서로 Lock을 걸지 않음 |
3. MVCC와 Isolation Level
각 격리 수준(Isolation Level)에 따라 **"읽기 시점"**과 MVCC의 버전 선택 방식이 달라진다.
(1) Read Uncommitted
- MVCC가 아닌 Lock 기반에서나 사용됨.
- MVCC를 사용하는 DB에서는 의미가 없음 (항상 커밋된 데이터만 보기 때문).
- Oracle은 이 레벨을 지원하지 않음.
(2) Read Committed (기본 격리 수준 in Oracle)
- "읽기 순간" 기준으로 커밋된 데이터를 읽는다.
- 하나의 트랜잭션 내에서 같은 쿼리를 두 번 실행해도 다른 결과가 나올 수 있다.
- Oracle에서는 SELECT할 때마다 최신 커밋된 버전을 다시 조회한다.
-- Session A
BEGIN;
UPDATE products SET price = 200 WHERE id = 1;
-- Session B
SELECT price FROM products WHERE id = 1; -- 100 (기존값)
-- Session A
COMMIT;
-- Session B
SELECT price FROM products WHERE id = 1; -- 200 (변경 반영됨)
(3) Repeatable Read
- 트랜잭션이 시작된 시점의 커밋된 데이터를 계속 유지.
- 같은 쿼리를 반복해도 일관된 결과.
- Oracle에서는 Serializable로 통합 처리됨 (정확히는 snapshot 기반 직렬화).
(4) Serializable (in Oracle)
- 트랜잭션 간 충돌을 방지하기 위해 충돌 탐지 후 오류 발생.
- Oracle은 MVCC를 활용하여 Serializable 격리 수준에서도 Lock을 사용하지 않음.
- 읽기 시점에 없는 데이터에 대해 다른 트랜잭션이 insert/update하면, 충돌이 발생해 ORA-08177 오류를 던짐.
-- Session A
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM orders WHERE id = 10;
-- Session B
INSERT INTO orders (id, ...) VALUES (10, ...);
COMMIT;
-- Session A
-- 다시 같은 조건으로 insert 시도 시 ORA-08177
INSERT INTO orders (id, ...) VALUES (10, ...); -- 실패
4. MVCC와 Recoverability
- MVCC는 commit된 데이터만 읽기 때문에, 자연스럽게 non-repeatable read, dirty read 방지
- 하지만 **"write-write conflict"**는 막지 못한다 → 예: Lost Update
예시: Lost Update
-- Session A
SELECT qty FROM stock WHERE id = 1; -- 10
-- Session B
SELECT qty FROM stock WHERE id = 1; -- 10
-- Session A
UPDATE stock SET qty = 9 WHERE id = 1;
-- Session B
UPDATE stock SET qty = 8 WHERE id = 1;
5. Lost Update 방지를 위한 전략
- MVCC 환경에서 Repeatable Read 수준이라도 lost update는 발생할 수 있다.
- 이를 막기 위해서는 명시적인 버전 체크 혹은 충돌 탐지(commit 시점에) 필요
Oracle에서 해결법
- Optimistic Locking (애플리케이션 단 버전 필드 사용)
- Serializable 격리 수준 사용
→ insert/update 충돌 발생 시 ORA-08177 발생
6. 관련 심화 개념
개념 | 설명 |
Undo Segment | MVCC의 과거 버전을 보존하기 위한 영역. 오래된 쿼리 또는 Rollback 시 필요 |
Read Consistency | 트랜잭션이 항상 동일한 시점의 데이터를 읽을 수 있도록 보장 |
Snapshot | 트랜잭션이 시작할 때의 커밋된 데이터 상태 |
First-updater-wins | 동일 데이터에 대해 먼저 update한 트랜잭션이 우선권을 갖는 전략 (MySQL의 InnoDB) |
7. Oracle vs 다른 DB의 MVCC 차이
DBMS | MVCC 방식 | 특징 |
Oracle | Undo Segment 기반 | 읽기 일관성 제공, 모든 격리 수준에서 MVCC 적용 |
PostgreSQL | Tuple 버전 유지 | Vacuum 필요, Snapshot을 쿼리 전체에 고정 |
MySQL (InnoDB) | Row-based version | repeatable read에서 phantom read 방지 안됨 (gap lock 보완 필요) |
정리 요약
- MVCC는 Lock 없이 동시성을 제공
- Read는 시점 기준으로 과거 버전 조회
- Write는 새 버전 생성 → Undo에 과거 기록 저장
- 격리 수준에 따라 “읽기 시점”이 달라진다
- Oracle은 Read Committed, Serializable에 MVCC 적용
- 충돌 방지를 위해 Serializable, Optimistic Locking, 버전 필드 등을 고려해야 한다
'CS지식 > 데이터베이스 (Database)' 카테고리의 다른 글
(데이터베이스) 설계의 기초: Functional Dependency 정리 (0) | 2025.05.23 |
---|---|
(데이터베이스) DB 스키마 설계 주의사항 (0) | 2025.05.23 |
(데이터베이스) Lock, Two-Phase Locking(2PL), 데드락 정리(예제 포함) (0) | 2025.05.21 |
(DB)트랜잭션 이상 현상 , Isolation Level 정리 (SQL-92 기준) (0) | 2025.05.20 |
(데이터베이스) 트랜잭션 스케줄링 완전 분석: Recoverable, Cascadeless, Strict 스케줄의 모든 것 (0) | 2025.05.19 |