본문으로 건너뛰기

10.4 통계 뷰

PostgreSQL은 자기 상태를 SQL로 조회 가능한 뷰들로 노출합니다. pg_stat_*로 시작하는 시스템 뷰들입니다. 실시간 활동·누적 카운터·진행률·복제 상태를 모두 봅니다. 운영자가 이 뷰들을 알아 두면 외부 모니터링 도구 없이도 90%는 진단 가능합니다.

큰 분류

카테고리뷰 (대표)
활동 / 세션pg_stat_activity
누적 활동pg_stat_database, pg_stat_user_tables, pg_stat_user_indexes
WAL · 체크포인트pg_stat_wal, pg_stat_bgwriter, pg_stat_checkpointer (PG 17+)
I/O (PG 16+)pg_stat_io
복제pg_stat_replication, pg_stat_wal_receiver, pg_stat_subscription, pg_replication_slots
진행률pg_stat_progress_* (vacuum, create_index, basebackup, copy, cluster, analyze)
쿼리pg_stat_statements (확장)
SSL · GSSAPIpg_stat_ssl, pg_stat_gssapi
BGW · autovacuumpg_stat_subscription_stats, pg_stat_database_conflicts

pg_stat_activity — 세션 1줄

가장 자주 보는 뷰. 현재 모든 backend 정보.

SELECT pid, backend_type, state, wait_event_type, wait_event,
       xact_start, query_start, query
  FROM pg_stat_activity
 WHERE state = 'active'
 ORDER BY query_start;

주요 컬럼:

컬럼의미
pid프로세스 ID
backend_typeclient backend, autovacuum worker, walsender, …
stateactive, idle, idle in transaction, …
wait_event_type / wait_event대기 중이면 무엇
xact_start, query_start, state_change시각
query현재 SQL
client_addr, client_port, application_name클라이언트 정보
backend_xmin이 backend의 xmin (vacuum horizon)

pg_stat_database — DB 단위 누적

SELECT datname,
       numbackends, xact_commit, xact_rollback,
       blks_read, blks_hit,
       round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 1) AS cache_hit_pct,
       tup_returned, tup_fetched,
       tup_inserted, tup_updated, tup_deleted,
       conflicts, deadlocks, temp_files, temp_bytes,
       stats_reset
  FROM pg_stat_database
 WHERE datname IS NOT NULL;
핵심 지표권장
cache_hit_pct99%+ 좋은 상태
deadlocks0 권장. 증가하면 운영 점검
temp_files·temp_byteswork_mem 부족 시 자람
xact_commit / (commit + rollback)비정상 rollback 비율

pg_stat_user_tables — 테이블 누적

SELECT schemaname, relname,
       n_live_tup, n_dead_tup,
       n_tup_ins, n_tup_upd, n_tup_del,
       n_tup_hot_upd,
       seq_scan, idx_scan,
       last_vacuum, last_autovacuum,
       last_analyze, last_autoanalyze
  FROM pg_stat_user_tables
 ORDER BY n_tup_upd DESC
 LIMIT 10;
점검
dead_tup / live_tupBLOAT (8.1)
n_tup_hot_upd / n_tup_updHOT 비율 (4.3)
seq_scan vs idx_scan인덱스 누락 신호
last_*autovacuum이 도는지

pg_stat_user_indexes

SELECT relname AS table, indexrelname AS index,
       idx_scan, idx_tup_read, idx_tup_fetch,
       pg_size_pretty(pg_relation_size(indexrelid)) AS size
  FROM pg_stat_user_indexes
 ORDER BY idx_scan;

idx_scan = 0이고 큰 인덱스는 미사용 — drop 후보 (6.6).

pg_stat_wal (PG 14+)

SELECT wal_records, wal_fpi, wal_bytes,
       wal_buffers_full, wal_write, wal_sync,
       wal_write_time, wal_sync_time, stats_reset
  FROM pg_stat_wal;
컬럼의미
wal_records생성된 WAL record 수
wal_fpifull-page image 수 — 체크포인트 직후 큼
wal_bytes총 바이트
wal_buffers_fullWAL buffer 부족으로 flush 강제 — 크면 wal_buffers 키움
wal_sync_timefsync 누적 시간

WAL 생성량은 복제·archive 용량 계획의 핵심 입력합니다.

pg_stat_bgwriter / pg_stat_checkpointer

SELECT * FROM pg_stat_bgwriter;
SELECT * FROM pg_stat_checkpointer;   -- PG 17+
컬럼의미
checkpoints_timed시간 기반 체크포인트
checkpoints_reqWAL 크기 기반 — 이게 timed보다 크면 max_wal_size 키워야
checkpoint_write_time / checkpoint_sync_time평균 시간
buffers_checkpoint / buffers_clean / buffers_backend누가 dirty page를 썼나 (4.1)
maxwritten_cleanbgwriter가 한도까지 쓴 횟수 — bgwriter 부족

pg_stat_io (PG 16+)

SELECT backend_type, context, object, reads, writes, evictions, extends
  FROM pg_stat_io
 ORDER BY reads + writes DESC;

이전엔 pg_stat_database.blks_read로 거칠게만 봤던 I/O를 backend type × context × object로 세분화. 매우 강력. 운영 모니터링의 새 표준입니다.

context의미
normal일반 SELECT/UPDATE
vacuumautovacuum/vacuum
bulkreadseq scan strategy (4.1)
bulkwriteCOPY 등

pg_replication_slots

SELECT slot_name, slot_type, active, restart_lsn, confirmed_flush_lsn,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS lag,
       wal_status
  FROM pg_replication_slots;
wal_status의미
reserved정상
extendedwal_keep_size 초과해 보존 중
unreserved곧 잘릴 위험
lostWAL 이미 잘림 — 복제 불가

pg_stat_progress_*

진행률 추적 뷰들.

추적
pg_stat_progress_vacuumVACUUM (PG 9.6+)
pg_stat_progress_analyzeANALYZE (PG 13+)
pg_stat_progress_create_indexCREATE INDEX (PG 12+)
pg_stat_progress_basebackuppg_basebackup (PG 13+)
pg_stat_progress_copyCOPY (PG 14+)
pg_stat_progress_clusterCLUSTER / VACUUM FULL (PG 12+)
SELECT pid, datname, phase,
       heap_blks_scanned, heap_blks_total,
       round(100.0 * heap_blks_scanned / nullif(heap_blks_total, 0), 1) AS pct
  FROM pg_stat_progress_vacuum;

장시간 작업의 진행률 확인은 운영 안정성의 핵심입니다.

stats reset

SELECT pg_stat_reset();                       -- 현재 DB 모든 통계
SELECT pg_stat_reset_shared('bgwriter');      -- 특정 영역만
SELECT pg_stat_reset_single_table_counters('orders'::regclass::oid);

운영 중에는 자주 reset 안 함 — 누적 값으로 장기 추이를 봅니다. 변경 직후만 reset 후 측정 권장합니다.

모니터링 쿼리 모음 — 한 줄 점검

-- TOP 5 슬로우 쿼리 (pg_stat_statements 필요)
SELECT mean_exec_time, calls, total_exec_time, LEFT(query, 100) FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;

-- 오래된 idle in transaction
SELECT pid, usename, datname, state, now() - xact_start AS age, query FROM pg_stat_activity WHERE state LIKE 'idle in transaction%' AND xact_start < now() - interval '5 min';

-- 락 대기
SELECT pid, pg_blocking_pids(pid), query FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid)) > 0;

-- replication lag (primary에서)
SELECT application_name, state, write_lag, flush_lag, replay_lag FROM pg_stat_replication;

정리

  • 통계 뷰는 운영자의 표준 인터페이스 — SQL 한 줄로 클러스터 상태 확인
  • pg_stat_activity(실시간), pg_stat_database(누적), pg_stat_user_tables(테이블별)이 일상 도구
  • PG 14+ pg_stat_wal, PG 16+ pg_stat_io, PG 17+ pg_stat_checkpointer로 점점 정밀
  • pg_stat_progress_*로 장시간 작업 진행률
  • 외부 모니터링(Prometheus exporter)도 이 뷰들을 긁어 메트릭 만듦

다음 절(10.5)에서는 가장 강력한 쿼리 분석 도구 — **pg_stat_statements**를 봅니다.