MVCC (MySQL, PostgreSQL)

impmonzz·2025년 4월 9일

MySQL vs PostgreSQL: MVCC 비교 분석

데이터베이스에서 동시성을 관리하는 방법은 성능과 데이터 무결성에 큰 영향을 미칩니다. MySQL과 PostgreSQL은 둘 다 MVCC(Multi-Version Concurrency Control)를 지원하지만, 그 구현 방식과 동작 메커니즘이 다릅니다. 이 글에서 두 데이터베이스의 MVCC를 비교하며, 각각의 장단점과 적합한 사용 사례를 살펴보겠습니다.

MVCC란?

구현 방식

MySQL은 주로 InnoDB 스토리지 엔진에서 MVCC를 구현합니다. InnoDB는 MySQL의 기본 스토리지 엔진으로, 트랜잭션 지원, 외래 키 제약, 그리고 MVCC를 제공하는 강력한 엔진입니다. InnoDB는 Undo Log를 활용해 이전 버전의 데이터를 저장합니다. 트랜잭션이 데이터를 수정하면, 수정 전 데이터는 Undo Log에 기록되고, 다른 트랜잭션은 이 로그를 참조해 일관된 읽기(Consistent Read)를 수행합니다.

  • 스냅샷 격리(Snapshot Isolation): READ COMMITTED와 REPEATABLE READ 격리 수준에서 MVCC가 동작합니다. 트랜잭션이 시작될 때 스냅샷을 생성해 해당 시점의 데이터를 읽습니다.
  • 행 수준 잠금(Row-Level Locking): 쓰기 작업 시 행 단위로 잠금을 걸어 동시성을 관리합니다.

장점

  • 읽기와 쓰기 작업 간의 간섭이 적어, 읽기 중심 워크로드에서 성능이 뛰어납니다.
  • Undo Log를 활용하므로 디스크 공간을 효율적으로 사용합니다(일정 조건 하에서).

단점

  • Undo Log가 커지면 성능 저하가 발생할 수 있습니다.
  • Vacuuming(오래된 데이터 정리) 과정이 없어, 롤백 세그먼트가 비효율적으로 관리될 가능성이 있습니다.
  • REPEATABLE READ 수준에서 팬텀 읽기(Phantom Read)가 발생할 수 있습니다.

PostgreSQL의 MVCC

구현 방식

PostgreSQL은 다중 버전 저장 방식을 사용합니다. 데이터가 수정될 때마다 새로운 버전의 튜플(Tuple)을 생성하고, 이전 버전은 그대로 유지됩니다. 각 튜플에는 트랜잭션 ID와 유효성 정보가 포함되어 있어, 트랜잭션이 어떤 버전을 볼지 결정합니다.

  • 가시성 체크(Visibility Check): 읽기 작업 시 트랜잭션 ID를 확인해 해당 데이터가 현재 트랜잭션에서 보이는지 판단합니다.
  • Vacuum: 오래된 튜플을 정리하기 위해 주기적으로 Vacuum 프로세스를 실행합니다.

장점

  • 트랜잭션 격리 수준(Serializable 포함)이 강력하게 보장됩니다.
  • 쓰기 작업이 읽기 작업을 차단하지 않아 높은 동시성을 제공합니다.
  • 롤백이 간단하고 빠릅니다(새로운 버전만 삭제하면 됨).

단점

  • Vacuum 작업이 필요하므로 유지보수 부담이 있습니다.
  • 디스크 공간 사용량이 증가할 수 있습니다(특히 업데이트가 빈번한 경우).
  • 가시성 체크로 인해 읽기 성능이 약간 저하될 수 있습니다.

주요 차이점 비교

특성MySQL (InnoDB)PostgreSQL
버전 저장 방식Undo Log에 이전 데이터 저장새로운 튜플 생성
정리 메커니즘자동 롤백 세그먼트 관리Vacuum 필요
격리 수준READ COMMITTED, REPEATABLE READREAD COMMITTED, SERIALIZABLE 등
디스크 사용상대적으로 효율적업데이트 빈도에 따라 비효율적 가능
성능읽기 중심 워크로드에 강점복잡한 트랜잭션 처리에 강점

어떤 데이터베이스를 선택해야 할까?

MySQL이 적합한 경우

  • 읽기 작업이 많고, 간단한 트랜잭션을 처리하는 애플리케이션(예: 웹 애플리케이션, CMS).
  • 디스크 공간을 절약하고 유지보수 부담을 줄이고 싶은 경우.
  • 기존 MySQL 기반 인프라를 활용해야 할 때.

PostgreSQL이 적합한 경우

  • 복잡한 트랜잭션과 높은 데이터 무결성이 필요한 애플리케이션(예: 금융 시스템, 분석 플랫폼).
  • SERIALIZABLE 격리 수준 등 강력한 동시성 제어가 필요한 경우.
  • JSON, GIS 등 고급 데이터 타입을 활용하려는 경우.

3줄 요약

  1. MySQL의 InnoDB는 Undo Log로 MVCC 짜놓고 읽기 퍼포먼스 챙김, PostgreSQL은 튜플 새로 뽑아서 트랜잭션 격리 빡세게 잡음.

  2. InnoDB는 정리 자동으로 해줘서 편한데, PostgreSQL은 Vacuum 돌려야 해서 디스크 신경 좀 써야 함.

  3. 읽기 많으면 MySQL, 트랜잭션 복잡하면 PostgreSQL을 써보자

0개의 댓글