Postgres를 느리게 만드는 방법

9 hours ago 1

  • Postgres 성능을 극도로 저하시킬 수 있는 파라미터 조합에 대한 실험적 접근 소개
  • 일반적으로 캐시, 인덱스, WAL, I/O 등 다양한 요소를 역으로 튜닝함
  • shared_buffers, autovacuum, WAL 관련 옵션을 극단적으로 조작하여 TPS 42,000배 하락 달성
  • 새로운 Postgres 18/19 버전의 io_method 및 io_workers 등 최신 기능도 적용해 단일 I/O 스레드 제한 실험 수행
  • 실험 결과 Postgres 설정 파일만으로도 극단적 성능 저하가 가능함을 입증함

개요

이 글은 일반적으로 빠르게 만드는 데 집중하는 Postgres 튜닝과 반대로, 오로지 느리게 만드는 것을 목표로 하여 다양한 PostgreSQL 설정값만을 바꿔 성능을 한계까지 저하시킨 실험 내용임.
테스트는 BenchBase의 TPC-C 워크로드(128창고, 100커넥션, 각각 최대 10,000트랜잭션/초 시도, 최신 Postgres 19devel, Ryzen 7950x, 32GB RAM, 2TB SSD 환경, 120초 진행) 기반임.
기본값에서 성능은 7082 TPS였으며, 각 파라미터 조작을 통해 얼마나 느려지는지 단계별로 관찰함.

캐싱 대폭 줄이기

  • Postgres는 disk I/O를 줄이기 위해 강력한 캐시(shared_buffers) 를 활용함
  • 기본값(10GB)에서 shared_buffers를 8MB로 감소시, TPS가 1/7 수준(1052 TPS)으로 하락함
  • cache hit 비율이 99.90%에서 70.52%로 감소, read syscall 300배 이상 증가 현상 관측
  • 128kB까지 줄이려 시도했으나, Postgres는 최소 약 2MB까지만 허용하여 485 TPS로 추가 하락함

백그라운드 작업 증가(autovacuum 튜닝)

  • autovacuum 관련 모든 기준치를 최소화하여, 거의 매 작업마다 vacuum이 동작하게 만듦
    • autovacuum_vacuum_insert_threshold=1, autovacuum_naptime=1 등 조합
    • vacuum이 실질적 일이 없는 상태로도 거의 1초마다 반복 동작
  • 이 과정에서 maintenance_work_mem을 128kB로 축소, 모든 autovacuum 로깅 활성화
  • 이 결과, TPS가 293으로 감소(원래 대비 1/20 이하)
  • autovacuum 관련 실시간 로그를 통해 실제 빈번한 백그라운드 작업이 성능 저하의 원인임을 확인

WAL(Write-Ahead Log) 쓰기 작업 최악화

  • WAL 관련 파라미터를 전부 최악으로 조정
    • wal_writer_flush_after=0, wal_writer_delay=1, wal_sync_method=open_datasync 등
    • checkpoint를 30초마다 강제, min/max_wal_size=32MB로 최소한 유지
    • wal_level=logical, wal_log_hints=on 등 WAL에 불필요한 정보까지 기록
    • track_wal_io_timing, summarize_wal 등 추가 부하도 활성화
  • 이 결과 TPS는 98까지 감소(원래 대비 1/70 이하)
  • 로그에서 checkpoints가 몇백 ms마다 반복되는 등 비정상적 동작 확인

인덱스 효과 제거

  • 인덱스 사용이 모두 비용 최대로 계산되는 값(random_page_cost=1e300, cpu_index_tuple_cost=1e300)으로 설정, 실질적으로 인덱스 무효화
  • shared_buffers를 8MB까지 증액(안정성 확보용), TPS는 0.87까지 하락(7000배 느려짐 달성)

I/O 단일 스레드 강제

  • 최신 Postgres 18+ 기능 활용
  • io_method=worker, io_workers=1로 모든 I/O를 단일 워커 스레드로 강제
  • TPS가 0.016으로 추가 하락(42,000배 느려짐)
  • 100커넥션, 120초 실험에서 11트랜잭션만 성공할 정도로 제한적 성능

결론 및 재현 안내

  • 총 32가지 파라미터 조작만으로 운영 DB를 사실상 "마비"상태까지 만들 수 있음을 입증함
  • 오로지 postgresql.conf 설정만 건드려 성능 저하를 극대화할 수 있음
  • 실험 재현을 원하는 사용자는 BenchBase Postgres, 위 명시된 TPC-C 환경, 그리고 모든 설정 목록 참조
  • 일부 부가 파라미터나 추가적인 느리게 만들기 시도는 미포함

요약 파라미터 목록

  • shared_buffers = 8MB
  • autovacuum 관련 thresholds/scale_factor = 0~1 최저화
  • vacuum 관련 비용 및 메모리/로그: 최저&최대화
  • WAL 관련 sync/flush/로그/레벨 등: 느리게 유지
  • 인덱스 관련 random_page_cost, cpu_index_tuple_cost: 1e300 지정
  • io_method = worker, io_workers = 1
  • 기타 상세 값은 본문 목록 참조

마무리

  • 단순히 postgresql.conf 파일만으로 극심한 성능 저하를 유발할 수 있음
  • 실무에서는 해당 조합을 반대로(효율적 성능 개선)에 참고할 가치가 있음
  • 실험 진행 중 필자의 허리 통증으로 인한 중단 언급으로 글 마침

Read Entire Article