Postgres Auto vacuum 의 중요성
PostgreSQL 를 사용하다 보면 어느 순간 디스크가 기하급수적으로 늘어난다.
DELETE / UPDATE 가 지속적으로 발생하면서 디스크는 크게 줄지 않고, 비용은 점점 올라간다.
뿐만 아니라 쿼리 성능 저하, 인덱스 비대화의 문제로 데이터베이스의 성능이 점차 떨어진다.
Auto vacuum이 안 돌면 생기는 성능 이슈
1. 쿼리 성능 저하
UPDATE, DELETE가 많아지면 dead tuples 이 쌓인다.
PostgreSQL은 MVCC 방식이라, 삭제된 데이터도 실제로는 지워지지 않고 남아 있는데 이걸 지워주는 게 vacuum이다.
vacuum 은 백그라운드에서 autovacuum 이 실행되며, 쿼리로 명령어를 작성할 수 도 있다.
이것이 제대로 돌지 않으면 테이블이 점점 무거워진다.
이 과정으로 전체 테이블 스캔 비용 증가, 인덱스가 비효율적으로 커진다.
2. 인덱스 비대화
인덱스도 dead tuple을 포함한 상태가 계속 유지된다.
Auto vacuum은 인덱스를 정리하지 않기 때문에 REINDEX 가 필요하다.
인덱스가 커지면 쿼리 플래너가 잘못된 판단을 하기도하며 아주 가끔 REINDEX을 할 필요가 있다.
REINDEX 를 진행할 경우 테이블에 락이 걸려 운영중인 서비스에 문제가 발생한다.
3. 트랜잭션 ID wraparound 위험
PostgreSQL 은 트랜잭션 ID를 32bit로 관리하며 일정 수준을 지나면 기존 데이터가 무효화될 수 있다.
Auto vacuum은 이를 방지하기 위해 freeze 작업을 수행하기도 한다.
만약 이 작업도 안 되면 PostgreSQL는 전체 읽기/쓰기를 중단시키며 강제로 vacuum을 시도하기도 한다.
이때 호러물마냥 메시지 나온다.
4. 디스크 계속 증가
Auto vacuum이 안 돌면 dead tuple 이 지워지지 않기 때문에 디스크 사용량이 증가한다.
AWS 의 Aurora를 사용할 경우 디스크가 자동 확장되므로 불필요한 요금을 내야할 수 도 있다.
Auto vacuum 대응
죽은 튜플을 보는 방법
SELECT relname, n_dead_tup
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;
죽은 튜플 수동 정리 방법
- 죽은 튜플을 정리하지만 디스크 공간은 줄어들지 않음 (reuse만 가능)
VACUUM tablename;
- ANALYZE 같이 정리하길 원할 경우
VACUUM ANALYZE tablename;
- 테이블을 깔끔하게 정리해서 디스크 공간을 회수. (단점: 테이블 락 걸림, 서비스 중에는 서비스 중단하고 하던가 해야함)
VACUUM FULL tablename;
Autovacuum 환경 설정 수정 방법
파라미터설명예시 값 (postgresql.conf)
autovacuum | Autovacuum 기능 활성화 여부 | on (기본값) |
autovacuum_naptime | autovacuum이 실행되는 최소 대기 시간 (초) | 1min |
autovacuum_vacuum_scale_factor | 테이블에서 일정 비율 이상 데이터가 변경되면 vacuum 실행 | 0.2 |
autovacuum_vacuum_threshold | autovacuum이 작동하기 위한 최소 튜플 변경 수 | 50 |
autovacuum_analyze_scale_factor | 통계를 갱신하기 위한 변경 비율 | 0.1 |
autovacuum_freeze_max_age | 트랜잭션 ID가 freeze를 해야 할 최대 나이 (트랜잭션 wraparound 방지) | 200000000 |
log_autovacuum_min_duration | autovacuum 작업 로그를 기록할 최소 실행 시간 | 0 (모든 실행 기록) |