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 · GSSAPI | pg_stat_ssl, pg_stat_gssapi |
| BGW · autovacuum | pg_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_type | client backend, autovacuum worker, walsender, … |
state | active, 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_pct | 99%+ 좋은 상태 |
deadlocks | 0 권장. 증가하면 운영 점검 |
temp_files·temp_bytes | work_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_tup | BLOAT (8.1) |
n_tup_hot_upd / n_tup_upd | HOT 비율 (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_fpi | full-page image 수 — 체크포인트 직후 큼 |
wal_bytes | 총 바이트 |
wal_buffers_full | WAL buffer 부족으로 flush 강제 — 크면 wal_buffers 키움 |
wal_sync_time | fsync 누적 시간 |
WAL 생성량은 복제·archive 용량 계획의 핵심 입력합니다.
pg_stat_bgwriter / pg_stat_checkpointer
SELECT * FROM pg_stat_bgwriter;
SELECT * FROM pg_stat_checkpointer; -- PG 17+| 컬럼 | 의미 |
|---|---|
checkpoints_timed | 시간 기반 체크포인트 |
checkpoints_req | WAL 크기 기반 — 이게 timed보다 크면 max_wal_size 키워야 |
checkpoint_write_time / checkpoint_sync_time | 평균 시간 |
buffers_checkpoint / buffers_clean / buffers_backend | 누가 dirty page를 썼나 (4.1) |
maxwritten_clean | bgwriter가 한도까지 쓴 횟수 — 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 |
vacuum | autovacuum/vacuum |
bulkread | seq scan strategy (4.1) |
bulkwrite | COPY 등 |
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 | 정상 |
extended | wal_keep_size 초과해 보존 중 |
unreserved | 곧 잘릴 위험 |
lost | WAL 이미 잘림 — 복제 불가 |
pg_stat_progress_*
진행률 추적 뷰들.
| 뷰 | 추적 |
|---|---|
pg_stat_progress_vacuum | VACUUM (PG 9.6+) |
pg_stat_progress_analyze | ANALYZE (PG 13+) |
pg_stat_progress_create_index | CREATE INDEX (PG 12+) |
pg_stat_progress_basebackup | pg_basebackup (PG 13+) |
pg_stat_progress_copy | COPY (PG 14+) |
pg_stat_progress_cluster | CLUSTER / 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**를 봅니다.