VACUUM 간단 정리
2025. 2. 16. 01:13ㆍDatabase/PostgreSQL
1. 개요
- PostgreSQL은 MVCC(Multi-Version Concurrency Control)을 사용하여 데이터를 관리
- MVCC는 트랜잭션 격리성과 동시성을 보장하는 대신, 불필요한 데이터(Dead Tuples)가 쌓이는 문제 유발
- 이를 해결하기 위해 VACUUM을 실행해야함
2. VACUUM이 필요한 이유
1. MVCC로 인해 삭제된 데이터(Dead Tuples)가 계속 남아 있음
- PostgreSQL은 데이터를 즉시 삭제하지 않고, 기존 데이터를 ‘Dead Tuple’로 유지
- 이는 트랜잭션 격리성과 동시성을 보장하기 위한 메커니즘
예시
DELETE FROM users WHERE id = 1;
- 이때
id = 1
데이터를 즉시 삭제하는 것이 아니라, 삭제되었다고 표시된 Dead Tuple로 남아 있음 - 트랜잭션이 롤백될 경우, 다시 복구될 수 있도록 보장하기 때문
- 하지만 이 Dead Tuple이 쌓이면?
- SELECT 성능 저하 → 불필요한 데이터까지 스캔해야 하므로 속도가 느려짐
- INSERT, UPDATE 성능 저하 → 새로운 데이터를 저장할 공간이 부족해지고, 디스크 사용량 증가
2. Dead Tuples가 인덱스에도 영향을 미침
- 테이블에 DELETE/UPDATE가 반복될 경우, 인덱스 내에서도 Dead Tuples가 포함
- 결과적으로 인덱스 크기가 불필요하게 증가하고, Index Scan 성능이 저하될 수 있음
예시
CREATE INDEX idx_users_email ON users(email);
SELECT * FROM users WHERE email = 'test@example.com';
- Dead Tuples가 많으면 불필요한 데이터까지 검색해야 하므로 속도가 느려짐
3. 디스크 공간 증가
- PostgreSQL은 UPDATE, DELETE 시 기존 데이터를 삭제하지 않고 새로운 데이터 버전을 생성
- VACUUM을 실행하지 않으면 불필요한 공간이 계속 증가하여 디스크를 낭비
예시
UPDATE users SET email = 'new@example.com' WHERE id = 1;
email
값이 변경될 때, PostgreSQL은 기존 데이터를 삭제하지 않고 새로운 버전의 데이터를 생성- 결과적으로 디스크 공간이 불필요하게 사용됨
3. VACUUM의 역할
- VACUUM은 Dead Tuples를 정리하고, PostgreSQL 성능을 유지하는 중요한 작업
기본적인 VACUUM
VACUUM users;
- Dead Tuples를 정리하지만, 디스크 공간은 회수하지 않음
- Autovacuum이 활성화되어 있으면 자동 실행됨
VACUUM FULL
VACUUM FULL users;
- Dead Tuples 정리 + 디스크 공간까지 반환
- 단점: 테이블이 완전히 잠김 (LOCK 발생) → 실행 중에는 해당 테이블에 대한 읽기/쓰기 작업 불가능
- 디스크 공간이 부족할 경우 필수 실행
ANALYZE (통계 업데이트)
VACUUM ANALYZE users;
- VACUUM과 함께 실행하면 쿼리 플래너가 최신 통계를 반영할 수 있도록 도움
- SELECT 쿼리 최적화에 필수적
- 인덱스 활용도를 높일 수 있음
4. VACUUM 실행 효과
항목 | VACUUM 전 | VACUUM 후 | 설명 |
---|---|---|---|
SELECT 속도 | 느림 | 빨라짐 | Dead Tuples 제거로 검색 범위 축소 |
INSERT / UPDATE 성능 | 저하됨 | 최적화됨 | 사용되지 않는 공간을 정리 |
디스크 사용량 | 증가 | 감소 | 불필요한 데이터 정리 |
인덱스 크기 | 커짐 | 줄어듦 | 인덱스 내 불필요한 Dead Tuples 제거 |
5. PostgreSQL의 Autovacuum 동작 방식
- Autovacuum : 자동으로 VACUUM을 실행하는 프로세스
- 하지만 Autovacuum이 즉시 실행되지 않을 수도 있기 때문에, 특정 상황에서는 수동 실행 필요
Autovacuum 관련 설정 (postgresql.conf)
autovacuum = on
autovacuum_naptime = 30s # 기본값: 1분 (너무 긴 경우 줄여줌)
autovacuum_vacuum_cost_limit = 2000 # 기본값: 200 (더 많은 테이블을 처리 가능)
Autovacuum이 작동하는 원리
- DELETE, UPDATE 등의 작업이 일정량 발생하면 Autovacuum 트리거됨
- VACUUM을 실행하여 Dead Tuples 제거
- 필요하면 ANALYZE도 자동 실행하여 통계 업데이트
Autovacuum이 작동 중인지 확인
SELECT * FROM pg_stat_activity WHERE query LIKE 'autovacuum%';
6. 언제 VACUUM을 실행해야 하는가?
- 대량의 DELETE 또는 UPDATE를 실행한 경우
- 디스크 사용량이 갑자기 증가한 경우
- SELECT 쿼리 성능이 느려진 경우
- Autovacuum이 너무 늦게 실행되는 경우
VACUUM을 직접 실행해야 할 때
VACUUM ANALYZE;
VACUUM FULL;
- (주의)
VACUUM FULL
은 테이블을 잠그기 때문에 트래픽이 적은 시간대에 실행하는 것이 좋음
결론
- PostgreSQL의 MVCC 특성상, Dead Tuples가 지속적으로 발생하므로 정기적인 VACUUM 실행이 필수
- Autovacuum이 작동하지 않는 경우, 성능 저하가 발생할 수 있으므로 수동으로 VACUUM 실행이 필요
- ANALYZE와 함께 실행하면 쿼리 플래너가 최신 정보를 반영하여 성능 최적화 가능
- 디스크 사용량이 많아지면 VACUUM FULL을 고려해야 하지만, 실행 중에는 테이블이 잠기므로 주의가 필요
'Database > PostgreSQL' 카테고리의 다른 글
PostgreSQL 복합 인덱스(Composite Index) 완벽 가이드 (0) | 2025.02.16 |
---|---|
PostgreSQL 조인 알고리즘 비교: 해시 조인(Hash Join), 중첩 루프 조인(Nested Loop Join), 병합 조인(Merge Join) (0) | 2025.02.16 |
PostgreSQL 성능 튜닝: ANALYZE vs EXPLAIN ANALYZE 차이점과 활용법 (0) | 2025.02.16 |
Dead Tuple (0) | 2025.02.16 |