본문 바로가기

데이터베이스

[Postgresql] Vacuum

728x90

 

/* PostgreSQL Dead Tuple와 Vacuum 이야기 */

PostgreSQL을 쓰다 보면 디스크 사용량이 자꾸 늘어나거나, 쿼리가 점점 느려지는 경험을 한다.
그 주범 중 하나가 바로 **Dead Tuple(죽은 튜플)**이다.

오늘은 Dead Tuple이 어떻게 처리되는지, 그리고 이를 청소하는 Vacuum이 어떻게 동작하는지,
Lazy Vacuum, Auto Vacuum, Vacuum Full까지 깔끔하게 정리해본다.

 

/* Dead Tuple은 왜 생기나? */

PostgreSQL은 UPDATE나 DELETE 시 기존 데이터를 바로 덮어쓰지 않는다.
대신 MVCC(Multi-Version Concurrency Control)라는 방식으로 새 버전을 만든다.

 

UPDATE users SET name = 'Ewan' WHERE id = 1;

 

  • 기존 튜플은 Dead Tuple이 된다. (다른 트랜잭션이 여전히 참조할 수도 있음)
  • 새로운 튜플이 페이지에 추가된다.

이렇게 되면 테이블 안에는 살아있는 튜플과 죽은 튜플이 섞여 있게 된다.

 

/* Dead Tuple이 지나가는 길: FSM과 VM */

Dead Tuple은 그냥 버려지는 게 아니다.
PostgreSQL은 이를 추적하고 재활용하기 위해 FSM(Free Space Map)과 VM(Visibility Map)을 사용한다.

  • FSM (Free Space Map)
    → 페이지 안에 얼마나 빈 공간이 있는지 저장.
    → 새로운 데이터가 들어올 때 "여기 빈자리 있어!" 하고 알려준다.
  • VM (Visibility Map)
    → 페이지의 모든 튜플이 visible(다른 트랜잭션에서 볼 수 있음) 상태인지 표시.
    → Vacuum이 "이 페이지는 건너뛰어도 된다"는 판단을 할 수 있게 해준다.

Dead Tuple이 생기면 FSM/VM에 표시가 되고, 다음 Vacuum 때 처리된다.

 

/* Lazy Vacuum: 페이지 내부 재활용 */

Lazy Vacuum은 말 그대로 “게으르게” 처리하는 방식이다.

  1. Dead Tuple이 있는 페이지를 찾아서
  2. 해당 공간을 다시 쓸 수 있게 마킹만 한다.
  3. 실제 디스크 파일 크기는 줄이지 않는다.

즉, 페이지 내부에서만 공간이 재활용된다.
이 방식의 장점은 빠르고 락을 최소화한다는 점이다.
단점은 디스크 파일 자체가 줄어들지 않기 때문에, 파일이 비대해진 상태라면 효과가 제한적이다.

 

/* Auto Vacuum: 알아서 청소부 */

매번 사람이 수동으로 VACUUM 치는 건 귀찮다.
그래서 PostgreSQL은 Auto Vacuum이라는 청소부를 내장하고 있다.

  • 일정 기준(Dead Tuple 비율, 변경 횟수 등)을 초과하면 자동 실행
  • Lazy Vacuum 방식으로 동작
  • 트랜잭션 ID wraparound 방지도 함께 수행
    • PostgreSQL에서 트랜잭션 ID(XID)가 21억 개 정도를 찍고 나면 다시 0부터 돌아오는 현상.

Auto Vacuum은 서비스 운영 중에 꾸준히 청소를 해주지만, 부하가 높은 시간대에는 약간의 성능 저하가 생길 수 있다.

 

/* 흐름 정리 */

Dead Tuple의 여정은 이렇게 된다.

UPDATE/DELETE
    ↓
Dead Tuple 생성
    ↓
FSM/VM에 표시
    ↓
Lazy Vacuum or Auto Vacuum → 페이지 내부 재활용
    ↓
(필요 시) Vacuum Full → 디스크 파일에서 완전 삭제

 

/* 마무리 */

PostgreSQL에서 Vacuum은 단순한 청소가 아니라 성능 유지와 데이터 무결성 보장을 위한 핵심 작업이다.
Auto Vacuum으로 평소 관리를 하고, 디스크를 줄여야 할 땐 Vacuum Full을 쓰면 된다.

다만, Vacuum을 무시하고 오래 방치하면 Dead Tuple이 쌓여서 쿼리 성능 저하 + 디스크 폭발이 발생할 수 있다.
결국 PostgreSQL에서의 성능 최적화는 청소 습관에서 시작된다고 봐도 과언이 아니다.

 

728x90

'데이터베이스' 카테고리의 다른 글

[Postgresql] Scan과 Join  (2) 2025.08.13
[Postgresql] Lock 락  (5) 2025.08.13
[Postgresql] 튜플 버전  (0) 2025.07.22
[Postgresql] MVCC (다중 버전 동시성 제어)  (0) 2025.04.15
[Postgresql] 아키텍처  (0) 2025.03.30