운영 환경에서 대규모 로그성 데이터를 다루다 보면, 테이블이 금방 수십~수백 GB로 커져버리는 경우가 많습니다. 특히 audit, log, history 같은 이력성 데이터는 시간이 지남에 따라 계속 누적되기 때문에 성능 저하와 관리 이슈가 발생하기 쉽습니다.

이런 문제를 해결하기 위해 PostgreSQL에서는 파티셔닝(partitioning) 기법을 활용할 수 있습니다. 그중에서도 pg_partman과 pg_cron 확장을 활용하면, 자동 파티션 생성·삭제 및 유지보수 스케줄링을 설정할 수 있습니다.


1. pg_partman을 이용한 파티션 테이블 생성

아래 예시는 cms.audits 테이블을 월 단위 파티션으로 관리하도록 설정한 코드입니다.


SELECT public.create_parent( 
p_parent_table => 'sample.audits', 
p_control => 'created_at', 
p_interval => '1 month', 
p_premake => 3, 
p_start_partition => date_trunc('month', CURRENT_DATE - interval '2 months')::text
PostgreSQL + pg_partman + pg_cron을 활용한 자동 파티션 관리 );
 
  • sample.audits 테이블을 기준으로 함
  • created_at 컬럼을 기준으로 1개월 단위 파티션 생성
  • p_premake = 3 → 앞으로 3개월치 파티션을 미리 생성
  • p_start_partition → 현재 시점 기준, 2개월 전부터 파티션 시작

2. 파티션 관리 정책 설정

파티션이 생성된 이후에는 보관 주기와 유지보수 방식을 설정합니다.

 
UPDATE public.part_config
SET retention = '5 years',
retention_keep_table = false,
retention_keep_index = false,
automatic_maintenance = 'on',
infinite_time_partitions = true
WHERE parent_table = ' sample.audits';
  • 보관 주기: 최근 5년치 데이터만 유지
  • retention_keep_table = false → 오래된 파티션 테이블 자동 삭제
  • retention_keep_index = false → 오래된 인덱스 자동 삭제
  • automatic_maintenance = on → 유지보수 자동 실행
  • infinite_time_partitions = true → 시간이 지나도 계속 파티션 확장

3. pg_cron으로 정기 유지보수 스케줄링

pg_cron을 이용하면 리눅스 cron처럼 PostgreSQL 내부에서 작업을 예약할 수 있습니다.

 
-- 매일 새벽 2시: 파티션 관리 실행
SELECT cron.schedule(
'partman-maintenance',
'0 2 * * *',
'
SELECT partman.run_maintenance(p_analyze :=false);'
);

-- 매주 일요일 새벽 3시: 파티션 관리 + ANALYZE 실행
SELECT cron.schedule(
'partman-analyze',
'0 3 * * 0',
'
SELECT partman.run_maintenance(p_analyze :=true);'
);
  • 매일 새벽 2시에 기본 유지보수 실행
  • 매주 일요일 새벽 3시에 유지보수 + 통계 갱신(ANALYZE) 실행

4. 활용 포인트

  • 대용량 로그성 데이터를 효율적으로 관리 가능
  • 자동화 덕분에 DBA가 수동으로 파티션을 만들고 삭제할 필요 없음
  • 성능 관리와 저장 공간 관리에 큰 도움이 됨
  • pg_partman은 월/일/시간 단위까지 다양한 파티션 주기를 지원

마무리

PostgreSQL 단독으로도 파티셔닝은 가능하지만, pg_partman을 활용하면 훨씬 더 손쉽게 자동 파티션 관리를 구현할 수 있습니다. 여기에 pg_cron을 붙이면 스케줄 기반으로 정기적인 유지보수까지 자동화할 수 있습니다.

운영 환경에서 로그성 데이터를 다루고 있다면, pg_partman + pg_cron 조합을 꼭 고려해보시길 추천드립니다.

+ Recent posts