PostgreSQL

PostgreSQL: pg_store_plans

dewstream 2025. 7. 10. 08:00
728x90

※ PostgreSQL: pg_store_plans.

※ Version: Linux 8.10 (Rocky), PostgreSQL 17.4, pg_store_plans 1.9.

 

안녕하세요. 듀스트림입니다.

 

오늘은 오랜만에 익스텐션 관련 내용입니다.

 

 

GitHub - ossc-db/pg_store_plans: Store execution plans like pg_stat_statements does for queries.

Store execution plans like pg_stat_statements does for queries. - ossc-db/pg_store_plans

github.com


1. pg_store_plans?

pg_store_plans는 PostgreSQL의 실행 계획을 저장하고 관리하는 익스텐션입니다.

구분 설명
목적 모든 SQL 문장의 실제 실행 계획을 샘플링이 아니라 누적 통계로 저장
활용 pg_stat_statements 의 queryid와 조인해 “어떤 쿼리가 어떤 계획으로 얼마나 자주/느리게” 실행됐는지 분석
주요 View pg_store_plans, pg_store_plans_info
주요 함수 pg_store_plans_reset(), pg_store_plans_*plan() (text/json/xml/yaml 변환)
필수 조건 shared_preload_libraries에 로드, compute_query_id = auto|on

2. 설치

이미 PostgreSQL이 설치되어 있다는 가정 하에 패키지는 git만 추가로 설치해 주시면 됩니다.

 

▸ git clone

cd ~
git clone https://github.com/ossc-db/pg_store_plans.git

 

▸ 설치

cd pg_store_plans

make USE_PGXS=1
make install USE_PGXS=1

 

▸ postgresql.conf 설정

vi $PGDATA/postgresql.conf

 

shared_preload_libraries = 'pg_store_plans'
compute_query_id = auto # auto|on
pg_store_plans.max = 10000
pg_store_plans.max_plan_length = '10000'
pg_store_plans.track = all  # 함수 내부 호출까지 수집
pg_store_plans.plan_storage = file # file | shmem

 

▸ 익스텐션 추가

psql
CREATE EXTENSION pg_store_plans WITH SCHEMA test;

 

+ 파라미터 목록

파라미터 기본값 설명
pg_store_plans.max 1000 추적·저장할 실행 계획(row) 최대 개수
초과 시 실행 횟수가 가장 적은 계획부터 제거됨
pg_store_plans.track top 누적 대상 범위
top (클라이언트 최상위 문장), all (함수 내부 등 포함), verbose (시스템 명령까지 전부), none 중 선택
pg_store_plans.max_plan_length 5000 raw(JSON-short) 형식으로 저장할 단일 계획 문자열 최대 바이트 수 (초과분은 잘림)
pg_store_plans.plan_storage file 계획 문자열 보관 위치
file (임시파일) vs shmem (공유메모리)
pg_store_plans.plan_format text plan 컬럼 표현 형식
text / json / xml / yaml / raw 중 선택
pg_store_plans.min_duration 0 ms 실행 시간이 이 값 이상일 때만 계획 저장
0이면 모든 문장을 기록
pg_store_plans.log_analyze off EXPLAIN ANALYZE 결과(실행 시간·실제 row 등)를 포함
켜면 오버헤드 ↑
pg_store_plans.log_buffers off EXPLAIN … BUFFERS 통계를 함께 저장
log_analyze와 무관하게 사용 가능
pg_store_plans.log_timing on 노드별 Timing 수집 여부
false로 두면 시스템 시계 호출 비용을 줄일 수 있음
pg_store_plans.log_triggers off 트리거 실행 통계를 포함
log_analyze = on일 때만 의미 있음
pg_store_plans.log_verbose off EXPLAIN VERBOSE 형태로 세부 플랜 노드를 기록
pg_store_plans.save on 서버 종료 시 통계 파일을 저장할지 여부
$PGDATA/pg_stat_tmp/pgsp_plan_texts.stat에 저장

 

++ plan_storage: file vs shmem

  • plan_storage=file (Default)
    • pg_store_plans.max가 충분히 크면 GC 거의 없음 → 무난
  • plan_storage=shmem
    • 초고 빈도 트래픽(수만 QPS) 환경에서 파일 I/O 타임스탬프 지연을 제거
    • shared_buffers 외 별도 shared memory 할당이 필요 → shared_memory_size 계산 필수

3. 사용법

▸ 실행 계획 확인

SELECT queryid, plan, calls, total_time/ calls AS ms_per_exec
FROM   pg_store_plans
ORDER  BY total_time DESC
LIMIT  10;

 

▸ 쿼리:계획 매핑(with pg_stat_statements)

SELECT s.query,
       p.plan,
       p.calls AS plan_calls,
       s.calls AS stmt_calls
FROM   pg_stat_statements s
JOIN   pg_store_plans     p USING (queryid)
WHERE  p.calls < s.calls;         -- 계획이 여러 번 바뀐 경우

 

▸ 리셋(통계 초기화)

SELECT pg_store_plans_reset();

 

▸ 계획 변경 추척

-- 같은 queryid 에서 planid 가 2 이상이면 계획 변동 발생
SELECT queryid, count(DISTINCT planid) AS plan_versions
FROM   pg_store_plans
GROUP  BY queryid
HAVING count(DISTINCT planid) > 1;

 

+ 슬로우 쿼리 후보만 수집

pg_store_plans.min_duration = 500 # 500ms 이상만
pg_store_plans.log_buffers  = on

4. 성능 및 리소스 영향

체크포인트 영향
Shared Memory pg_store_plans.max * 300B (메타) + max * max_plan_length(shmem일 때)
WAL 부하 없음 – 통계는 shared memory/임시파일에만 기록
CPU 오버헤드 실행 계획 계산 시간·JSON 직렬화 → log_timing 꺼서 최소화 가능
디스크 I/O plan_storage=file + GC 시 플러시 발생 → SSD 권장

오늘은 여기까지~

 

728x90

'PostgreSQL' 카테고리의 다른 글

PostgreSQL: 온라인 인덱스 작업(CONCURRENTLY)  (2) 2025.07.14
PostgreSQL: HOT(Heap-Only Tuple)  (2) 2025.07.11
PostgreSQL: Logical Replication  (0) 2025.07.02
PostgreSQL: io_combine_limit  (0) 2025.07.01
PostgreSQL: Partition  (4) 2025.06.26