PostgreSQL에서 Vacuum

큘피·2026년 5월 2일

데이터베이스

목록 보기
4/7

VACUUM이란?

더 이상 사용하지 않는 데이터를 정리하여 성능과 용량을 최적화하는 작업입니다.

PostgreSQL에서는 데이터를 수정하거나 삭제할 때 파일을 즉시 지우지 않고 '더 이상 유효하지 않음'이라고 표시만 해두는 방식을 사용하는데, 이를 정리해주는 과정이 VACUUM입니다.

왜 필요한가요?

MVCC 때문입니다. MVCC란 multiversion concurrency control으로 과거의 스냅샷을 활용해 읽기와 쓰기가 싸우지 않고(락을 걸지 않고) 동시성을 관리해 성능을 높이는 방법을 의미합니다. (이전에는 2PL)

  • UPDATE/DELETE 시: 행(Row)을 진짜 지우는 게 아니라, 기존 데이터는 "죽은 상태(Dead Tuple)"로 두고 새로운 데이터를 추가합니다.

  • 문제점: 이렇게 쌓인 죽은 데이터들이 공간만 차지하고 DB 성능을 갉아먹게 되는데, 이를 비대화(Bloat) 현상이라고 부릅니다.

VACUUM 명령어를 실행하면 다음과 같은 세 가지 중요한 작업이 일어납니다.

  • 공간 재활용: 죽은 튜플(Dead Tuple)이 차지하던 공간을 '새로운 데이터를 쓸 수 있는 공간'으로 마킹합니다.

  • 통계 정보 업데이트: ANALYZE와 함께 실행되어 쿼리 실행 계획을 짜는 Planner에게 최신 데이터 분포 정보를 제공합니다.

  • 트랜잭션 ID 겹침(Wraparound) 방지: Postgres의 트랜잭션 ID는 유한합니다. 이를 주기적으로 정리해주지 않으면 어느 순간 DB가 멈출 수 있는데, 이를 방지하는 필수 작업입니다.

Autovacuum: 알아서 정리를 해주긴 한다. 단, 1분마다 용량이 넘어가면 정리를 하는 느낌



명령어

기본 명령어

가장 많이 사용하는 조합은 VACUUM과 ANALYZE를 함께 쓰는 것입니다.

  • 현재 DB의 모든 테이블 정리:
    VACUUM;

  • 특정 테이블만 정리:
    VACUUM 테이블명;

  • 정리 후 통계 정보까지 업데이트 (권장):
    VACUUM ANALYZE 테이블명;

    • 정리 작업과 동시에 쿼리 최적화 도구(Planner)가 참고할 통계치를 갱신합니다.

상세 옵션 활용하기

최신 버전의 PostgreSQL에서는 괄호()를 사용한 구문을 권장합니다.

  • 진행 과정을 자세히 보기 (VERBOSE):
    VACUUM (VERBOSE, ANALYZE) 테이블명;

  • 디스크 용량을 실제로 반환하기 (FULL):
    VACUUM (FULL, FREEZE, VERBOSE, ANALYZE) 테이블명;

주의: FULL은 테이블에 강력한 락(Lock)을 걸어서 작업 동안 해당 테이블을 읽거나 쓸 수 없습니다. 서비스 점검 시간 등에만 사용하세요.


상태 확인을 위한 유용한 쿼리

명령어를 날리기 전에, "내 테이블에 청소가 얼마나 필요한가?"를 먼저 확인해 보는 것이 좋습니다.

죽은 데이터(Dead Tuples)가 얼마나 쌓였는지 확인:

SELECT 
	relname AS table_name, 
    n_dead_tup AS dead_tuples, -- 죽은 행 수
	last_vacuum,               -- 마지막 수동 VACUUM 날짜
	last_autovacuum            -- 마지막 자동 VACUUM 날짜
FROM pg_stat_all_tables
WHERE schemaname = 'public'
ORDER BY n_dead_tup DESC;
profile
취준생의 개발블로그

0개의 댓글