1060 단어
5 분
MVCC 그리고 PostgreSQL과 MySQL의 차이점
2026-06-29
태그 없음

MVCC#

MVCC는 다중 버전 동시성 제어의 약자이다. “기존 데이터를 덮어쓰기” 대신 “새 데이터를 쌓아올린다”로 요약할 수 있다.

그러니까 창팝으로 비유하자면…#

A교실에서 시험 치면 강제 -50점 B교실에서 시험 치면 강제 +50점 근데 몇 개월 전에 이 사실에 대해 모른 채로 A교실에서 시험 치기로 한 거임 교실을 바꾸려면 내년을 기약하고 똑같이 B교실이 +50점 줄지 모르는 상황 이 형평성에 가만히 있으면 정당한거냐? -메벤남

그냥넣어보고싶었음

이해가하나도안되잖아쿼리슝좍아#

Git으로 설명해보자.

  • 일단 main 브랜치에서 dev 브랜치를 딴다. (BEGIN)
  • 거기서 작업을 잔뜩 한다. (BEGIN 이후 쿼리)
  • 이제 작업사항들을…
    • main에 머지하거나(COMMIT)
    • 버린다(ROLLBACK)

PostgreSQL의 MVCC 구현#

어 코끼리는 짱커 그래서 디스크 더 쓸 거야

순서대로 알아보자면

  • BEGIN
  • 대충 뭔가 어마무시하게 많은 쿼리들
    • UPDATE: 쓰려는 원본 테이블 대신 임시 튜플을 만들고, 그곳에 UPDATE한다
    • SELECT: 원본 테이블과 임시 튜플(있으면)에서 찾는다
  • 이제 다 끝나고…
    • ROLLBACK: 임시 튜플을 버린다
    • COMMIT: 임시 튜플로 원본 테이블의 튜플을 교체한다(레퍼런스 교체 느낌으로 빠르다!)

그렇게 되면, 임시 튜플이나 원본 튜플들은 레퍼런스 없이 떠돌게 된다. 이는 VACUUM 시 GC된다.

이 구현의 장점은…

  • 어마무시하게 원자적이다. 레퍼런스 바꾸기 딸깍ㅋㅋ
  • SELECT가 여러 번 있어도 용량이 커지지 않는다
    • 락도 안 걸린다!

한편 단점은…

  • UPDATE 쿼리 많으면 산으로 간다. 디스크 용량 3배 사용 이벤트!

MySQL의 MVCC 구현#

img

순서대로 알아보자면

  • BEGIN
  • 대충 뭔가 많은 쿼리들
    • UPDATE: 원래 데이터를 undo log에 백업해두고, 원본 테이블을 바로 수정한다
    • SELECT: 현재 트랜잭션 격리 수준에 따라, undo log를 참고해서 적절한 버전의 데이터를 조회한다
  • 이제 다 끝나고…
    • ROLLBACK: undo log에 있는 원래 데이터로 복구한다
    • COMMIT: 변경사항을 확정한다. undo log는 더 이상 필요 없어지면 purge 스레드가 정리한다

undo log에는 두 종류가 있다:

  • insert undo log: INSERT 때 기록. 트랜잭션 커밋되면 바로 버려도 됨
  • update undo log: UPDATE/DELETE 때 기록. MVCC를 위해 커밋 후에도 당장 안 지울 수도 있음

트랜잭션 격리 수준별 동작 방식:

이 구현의 장점은…

  • 디스크 용량을 PostgreSQL보단 적게 쓴다. 원본을 바로 갈아치우니까
  • UPDATE가 많아도 튜플이 쌓이지 않는다

한편 단점은…

  • undo log 관리가 복잡하다. purge 스레드가 바쁘게 돈다
  • 롤백 시 undo log를 뒤져서 원복해야 하므로 오래된 트랜잭션일수록 롤백 비용이 크다
  • SELECT가 오래된 undo log까지 뒤져야 하면 느려질 수 있다, 위 단점과 시너지

그래서 뭐가 더 좋은데?#

둘 다 정답은 없다. 트레이드오프가 있을 뿐.

항목PostgreSQLMySQL
저장 방식새 튜플 추가 (append-only)원본 수정 + undo log
디스크 사용량UPDATE 많으면 죽을게상대적으로 안정적
SELECT 성능어 형이야 형은 락 거는 법 몰라격리 수준에 따라 다름
VACUUM / PurgeVACUUM 필요 (안 한다고? 그럼죽어)purge 스레드가 자동 처리
롤백 속도임시 튜플 삭제만 하면 끝undo log 뒤져서 복구해야 함
원자성레퍼런스 교체로 딸깍undo log 기반 복구

alt text

요약#

  • PostgreSQL: 읽기 성능이 중요하고, 디스크 넉넉할 때. MVCC가 진짜로 “쌓아올린다”에 가깝다
  • MySQL: 읽기/쓰기 밸런스가 중요하고, 디스크를 아껴야 할 때. Undo log로 타협한 MVCC