7.5 자동 파티션 관리 (pg_partman)
선언적 파티셔닝은 코어가 SQL 라우팅·pruning을 해 주지만, 새 파티션 생성과 오래된 파티션 정리는 운영자 몫입니다. 100개 넘는 파티션을 손으로 만들고 지우는 일은 비현실적. pg_partman(PostgreSQL Partition Manager)이 표준 자동화 도구입니다. EDB가 유지보수하고 BSD 라이선스로 공개돼 있으며, PGDG yum/apt 저장소에 패키지로 들어 있습니다.
설치
# RHEL/Rocky (PGDG)
sudo dnf install -y pg_partman_17
# Debian/Ubuntu (PGDG)
sudo apt-get install -y postgresql-17-partmanCREATE EXTENSION pg_partman;기본 스키마는 partman. 모든 메타데이터·함수가 이 스키마에 들어갑니다.
첫 파티션 등록
이미 선언적 파티션된 부모를 pg_partman에 등록합니다.
SELECT partman.create_parent(
p_parent_table := 'public.events',
p_control := 'created_at',
p_type := 'range',
p_interval := '1 month', -- 월 파티션
p_premake := 4, -- 앞으로 4개월치 미리
p_start_partition := '2026-01-01' -- 시작 시점
);이 한 번의 호출로:
events_p2026_01,events_p2026_02, …,events_p2026_06같은 자식이 자동 생성partman.part_config에 부모 설정이 기록 — 이후 유지보수의 기준
정기 유지보수
run_maintenance 함수가 모든 등록된 부모를 점검해 필요한 파티션을 생성하고, retention 정책에 맞게 오래된 파티션을 처리합니다.
-- 단일 부모
SELECT partman.run_maintenance('public.events');
-- 등록된 모든 부모
SELECT partman.run_maintenance();cron 또는 백그라운드 워커로 매시간/매일 호출합니다.
백그라운드 워커 (pg_partman_bgw)
shared_preload_libraries에 pg_partman_bgw를 넣으면 PostgreSQL이 자체적으로 유지보수를 돌린다 — cron 없이 자동입니다.
# postgresql.conf
shared_preload_libraries = 'pg_partman_bgw'
pg_partman_bgw.interval = 3600 # 1시간마다
pg_partman_bgw.role = 'postgres'
pg_partman_bgw.dbname = 'app_main'Retention 정책
오래된 파티션을 자동 처리합니다.
UPDATE partman.part_config
SET retention = '12 months', -- 1년 보유
retention_keep_table = false, -- DROP (false) 또는 DETACH만 (true)
retention_schema = 'archive' -- DETACH 시 옮길 스키마
WHERE parent_table = 'public.events';| 옵션 | 의미 |
|---|---|
retention | 보존 기간 (12 months, 90 days, …) |
retention_keep_table = true | 파티션을 부모에서 떼어내되 테이블 자체는 남김 |
retention_keep_table = false | DROP (완전 삭제) |
retention_schema | DETACH 시 옮길 스키마 — archive로 보내고 별도 S3 dump 가능 |
run_maintenance가 호출될 때 retention 정책에 걸리는 파티션을 자동 처리합니다.
자주 쓰는 시나리오
시계열 이벤트 (3개월 보유, 그 이전은 archive)
SELECT partman.create_parent(
p_parent_table := 'public.events',
p_control := 'created_at',
p_type := 'range',
p_interval := '1 day', -- 일 단위
p_premake := 7 -- 일주일치 미리
);
UPDATE partman.part_config
SET retention = '90 days',
retention_keep_table = true,
retention_schema = 'archive'
WHERE parent_table = 'public.events';시계열 + tenant subpartition
pg_partman은 subpartitioning도 지원하지만 복잡합니다. 운영 권장은 상위만 pg_partman으로 자동화, subpartition은 별도 자동화합니다.
운영 확인
-- pg_partman이 관리하는 부모들
SELECT parent_table, partition_interval, premake, retention
FROM partman.part_config;
-- 자식 파티션 목록
SELECT partman.show_partitions('public.events');
-- 마지막 유지보수 시각
SELECT * FROM partman.show_partition_info('public.events_p2026_05'::regclass::text);자체 cron + SQL — 작은 시스템에서
pg_partman을 안 쓰고 직접 자동화도 가능합니다. 작은 시스템·간단한 케이스:
# crontab — 매월 1일 새 파티션 생성
0 0 1 * * psql -c "
CREATE TABLE IF NOT EXISTS events_$(date +%Y_%m_next)
PARTITION OF events
FOR VALUES FROM ('$(date +%Y-%m-01_next)') TO ('$(date +%Y-%m-01_next_next)');
"운영 자동화로 보면 pg_partman이 훨씬 견고. 자체 cron은 시작 단계에서만 권장합니다.
핵심 함수 모음
| 함수 | 용도 |
|---|---|
create_parent(...) | 자동화 등록 |
run_maintenance(...) | 정기 유지보수 |
undo_partition(...) | 자식 데이터를 부모로 합침 |
partition_data_proc(...) | 옛 부모(상속 기반)의 데이터를 선언적 자식들로 이동 |
show_partitions(...) | 자식 목록 |
apply_constraints(...) | 자식의 NOT VALID constraint를 일괄 VALIDATE |
주의 — 잘못 쓰면 위험
| 주의 | 메모 |
|---|---|
| retention이 너무 짧음 | 의도치 않은 데이터 삭제. 검증 환경에서 먼저 확인 |
retention_keep_table = false로 잘못 설정 | DROP 후 복구 불가. 처음에는 true + archive 스키마 권장 |
| 매우 큰 파티션을 DROP | DROP은 빠르지만 자체 락 잡음. 짧은 점검 시간에 |
premake이 작음 | 새 파티션 생성이 늦어 INSERT 실패 가능. 보통 5+ |
| 백그라운드 워커 실패 추적 | 로그(logging_collector)로 감지 |
retention_keep_table = true로 동작 확인. 잘못 설정된 retention으로 데이터를 실수로 날린 사고가 가장 흔한 pg_partman 사고입니다.정리
- pg_partman = 선언적 파티션의 표준 자동화 도구입니다. PGDG 패키지로 설치
create_parent로 등록,run_maintenance로 정기 유지보수- 백그라운드 워커
pg_partman_bgw로 cron 없이 자동 - retention 정책으로 DROP·DETACH 자동 — 처음엔 archive 스키마로 안전망
- 작은 시스템은 자체 cron + SQL도 가능하지만 pg_partman이 정석
- premake은 최소 5 — INSERT 실패 방지
Part VII 파티셔닝이 끝났습니다. 다음 Part VIII에서는 유지보수 — VACUUM, ANALYZE, REINDEX, 정기 점검 — 를 봅니다.