[MySQL] MySQL vs PostgreSQL vs MsSQL

기훈·2025년 3월 17일

MySQL

목록 보기
3/23

RDBMS별 격리 수준(Isolation Level) 및 락 동작 원리 비교

짧은 연차동안 현업에서 3가지 RDBMS를 다뤄본 경험을 가지게 되었다.
이를 토대로 각 데이터베이스별 격리 수준(Isolation Level)에 따른 동작 원리와
읽기/쓰기 시 락 동작 방식을 비교하여 정리해보려 한다.


트랜잭션 격리 수준(Isolation Level)이란?

여러 트랜잭션이 동시에 처리될 때,
특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 여부를 결정하는 규칙이다.

격리 수준이 낮으면 동시성(Concurrency)은 높아지지만, 데이터 정합성 문제(Dirty Read, Non-Repeatable Read, Phantom Read 등)가 발생할 가능성이 있다.
격리 수준이 높으면 데이터 일관성은 좋아지지만, 동시성 저하와 락 경합 증가가 발생할 수 있다.


1. MySQL (InnoDB)

MySQL InnoDB는 MVCC(Multi-Version Concurrency Control) 기반으로 동작하여 읽기 작업에서 락을 최소화하면서도, 쓰기 작업 시에는 적절한 락을 걸어 데이터 무결성을 보장한다.

격리 수준읽기 시 락쓰기 시 락
Read Uncommitted없음 (커밋되지 않은 데이터도 읽음 → Dirty Read 발생)행 단위 배타락(X Lock)
Read Committed없음 (쿼리 실행 시점마다 최신 커밋 스냅샷 읽기)행 단위 배타락(X Lock)
Repeatable Read없음 (트랜잭션 시작 시점 MVCC 스냅샷 고정)행 단위 배타락(X Lock) + Next-Key Lock
Serializable암묵적 공유 락(S Lock) 적용행 단위 배타락(X Lock) + Next-Key Lock 범위 유지

상세 설명

  • 읽기 작업

    • Read Uncommitted는 커밋되지 않은 데이터도 읽기 때문에 Dirty Read가 발생할 수 있다.
    • Read Committed는 쿼리 실행 시점마다 최신 커밋된 스냅샷을 읽는다. 같은 트랜잭션 내에서도 쿼리마다 결과가 달라질 수 있어 Non-Repeatable Read가 발생한다.
    • Repeatable Read는 트랜잭션 시작 시점의 스냅샷을 고정해 같은 데이터를 여러 번 읽어도 결과가 변하지 않는다. MVCC 스냅샷 고정으로 Phantom Read도 방지된다.
    • Serializable은 SELECT 문에도 공유 락을 걸어 동시성을 제한한다.
  • 쓰기 작업

    • 모든 격리 수준에서 행 단위 배타락(X Lock)을 걸어 동시에 같은 행을 수정하지 못하도록 한다.
    • Repeatable Read는 추가로 Next-Key Lock(Record Lock + Gap Lock)을 걸어 인덱스 범위 내 새로운 행 삽입을 막는다. SELECT ... FOR UPDATE, SELECT ... FOR SHARE 같은 Locking Read에도 적용된다.
    • Serializable은 모든 읽기에 S Lock을 걸고 Next-Key Lock 범위를 유지해 완전한 직렬성을 보장한다.

2. PostgreSQL

PostgreSQL은 MVCC 기반이며, 락 정책과 충돌 감지 방식에 차이가 있다.

격리 수준읽기 시 락쓰기 시 락
Read Uncommitted지원하지 않음 (Read Committed로 동작)해당 없음
Read Committed없음 (쿼리 실행 시점마다 최신 커밋 스냅샷 읽기)행 단위 배타락(X Lock)
Repeatable Read없음 (트랜잭션 시작 시점 MVCC 스냅샷 고정)행 단위 배타락(X Lock) + 쓰기 시점 버전 충돌 감지 후 롤백
Serializable없음 (MVCC + SSI 적용)행 단위 배타락(X Lock) + SSI 의존성 추적으로 충돌 시 롤백

상세 설명

  • 읽기 작업

    • 모든 격리 수준에서 락 없이 MVCC 스냅샷 버전을 읽는다.
    • Read Committed는 쿼리 실행 시점마다 최신 커밋 데이터를 읽고, Repeatable Read는 트랜잭션 시작 시점 스냅샷을 고정한다.
    • Serializable은 SSI(Serializable Snapshot Isolation) 기법으로 락 없이 트랜잭션 간 의존성을 추적해 직렬성을 보장한다.
  • 쓰기 작업

    • 쓰기 시 행 단위 배타락(X Lock)을 걸어 동시 수정을 방지한다.
    • Repeatable Read는 UPDATE/DELETE 실행 시 내가 읽었던 버전이 최신인지 확인하고, 다른 트랜잭션이 이미 수정했다면 버전 충돌로 감지하여 롤백한다. 이 보호는 충돌하는 양쪽 트랜잭션 모두 RR 이상이어야 동작한다.
    • Serializable은 범위 락 없이 SSI 알고리즘으로 트랜잭션 간 읽기/쓰기 의존성(anti-dependency)을 추적하고, 커밋 시점에 직렬 실행으로 재현 불가능한 결과가 발생할 것으로 판단되면 롤백한다.

3. MSSQL (SQL Server)

MSSQL은 기본적으로 락 기반 동시성 제어를 사용하며, 옵션으로 MVCC 기반 Snapshot Isolation도 지원한다.

격리 수준읽기 시 락쓰기 시 락
Read Uncommitted없음없음
Read Committed기본: 짧은 시간 동안 S Lock 유지 / RCSI 활성화 시: 없음 (MVCC 읽기)행 단위 배타락(X Lock)
Repeatable ReadS Lock을 트랜잭션 종료까지 유지행 단위 배타락(X Lock)을 트랜잭션 종료까지 유지
Snapshot없음 (MVCC 스냅샷 읽기)행 단위 배타락(X Lock), 충돌 시 롤백
Serializable범위 락(Key-Range Lock) 유지행 단위 배타락(X Lock) + 범위 락 유지

상세 설명

  • 읽기 작업

    • Read Committed는 기본 설정에서 행을 읽는 동안 짧게 S Lock을 잡았다가 해제한다. 단, READ_COMMITTED_SNAPSHOT = ON(RCSI)을 활성화하면 S Lock 없이 MVCC 스냅샷으로 읽어 동시성이 높아진다.
    • Repeatable Read는 트랜잭션 종료 시까지 S Lock을 유지해 Non-Repeatable Read를 방지한다.
    • Snapshot 격리 수준은 MVCC 스냅샷을 읽어 락 없이 높은 동시성을 제공한다.
  • 쓰기 작업

    • 쓰기 작업은 행 단위 배타락(X Lock)으로 처리한다.
    • Serializable에서는 Key-Range Lock(범위 락)을 사용해 Phantom Read까지 방지한다.
    • Snapshot 격리에서 write-write 충돌 발생 시 트랜잭션이 롤백된다. 재시도는 자동으로 이루어지지 않으며, 애플리케이션 레벨에서 직접 처리해야 한다.

추가 설명: Phantom Read와 방지 메커니즘

Phantom Read는 트랜잭션 내에서 같은 조건으로 여러 번 조회할 때, 처음에는 없던 새로운 행이 다른 트랜잭션에 의해 삽입되어 결과가 달라지는 현상이다.

  • MySQL RR: MVCC 스냅샷 고정으로 새로 INSERT된 행이 보이지 않아 Phantom Read가 방지된다. 추가로 Next-Key Lock으로 갭을 잠가 쓰기 충돌도 차단한다.

  • PostgreSQL RR: 갭 락 없이 트랜잭션 시작 시점의 스냅샷이 고정되어 있어, 다른 트랜잭션이 새 row를 INSERT하고 커밋해도 보이지 않는다. 스냅샷 고정만으로 Phantom Read가 방지된다.

  • PostgreSQL SERIALIZABLE: SSI(Serializable Snapshot Isolation)는 Phantom Read보다 더 넓은 범위인 Write Skew까지 방지한다. 트랜잭션 간 읽기/쓰기 의존성을 추적해 직렬성 위반 가능성이 있으면 롤백한다.

  • MSSQL SERIALIZABLE: Key-Range Lock(범위 락)으로 조회 조건에 해당하는 인덱스 범위 전체를 잠가 새로운 행 삽입을 차단하여 Phantom Read를 방지한다.


마무리 및 참고 사항

  • MVCC 기반과 락 기반의 차이점

    • MySQL, PostgreSQL은 기본적으로 MVCC를 이용해 읽기 락을 최소화한다.
    • MSSQL은 기본 락 기반이지만 Snapshot Isolation 옵션으로 MVCC를 지원한다.
  • 격리 수준 선택 시 고려할 점

    • 높은 격리 수준은 데이터 일관성을 보장하지만, 동시성 저하와 락 경합 증가가 발생할 수 있다.
    • 낮은 격리 수준은 동시성은 높지만 데이터 정합성 문제가 발생할 수 있다.
    • 애플리케이션 요구사항과 트랜잭션 특성에 맞는 적절한 격리 수준 선택이 중요하다.

참고 자료

0개의 댓글