본문으로 건너뛰기

6.3 WAL/Checkpoint/Replication

쓰기 지연, WAL 디렉터리 증가, replica lag는 서로 연결되지만 같은 문제는 아닙니다. WAL 생성률, checkpoint, archive, sender/receiver/replay, replication slot을 분리해 봅니다.

PostgreSQL WAL checkpoint archive replication 단계별 진단 지점

WAL 디렉터리​

Exporter의 기본 wal collector는 pg_wal 안의 segment 수와 크기를 제공합니다.

pg_wal_segments
pg_wal_size_bytes

pg_wal_size_bytes가 증가하는 원인은 여러 가지입니다.

  • min_wal_size와 정상 recycle 범위
  • archive 실패
  • inactive replication slot
  • 느리거나 끊긴 replica
  • 긴 backup 또는 WAL 보존 설정
  • checkpoint 간격과 쓰기 burst

크기 증가만 보고 WAL file을 수동 삭제해서는 안 됩니다.

WAL 생성률​

PostgreSQL 원본 통계에서 확인합니다.

SELECT wal_records,
wal_fpi,
pg_size_pretty(wal_bytes) AS wal_bytes,
wal_buffers_full,
stats_reset
FROM pg_stat_wal;

Exporter version이 pg_stat_wal counter를 제공한다면 rate(...wal_bytes...[5m])로 bytes/s를 계산합니다. 제공하지 않는 경우 별도 collector나 SQL exporter를 도입하기 전에 실제 운영 질문과 cardinality를 정합니다.

Checkpoint​

PostgreSQL 17 이상에서는 stat_checkpointer collector를 선택적으로 활성화할 수 있습니다.

rate(pg_stat_checkpointer_num_timed_total[15m])
rate(pg_stat_checkpointer_num_requested_total[15m])
rate(pg_stat_checkpointer_write_time_total[15m])
rate(pg_stat_checkpointer_sync_time_total[15m])

Requested checkpoint가 자주 발생하면 max_wal_size, 수동 checkpoint 호출, restart와 연관성을 봅니다. Write와 sync 시간이 증가하면 node disk latency, dirty page 쓰기, storage throughput을 함께 확인합니다.

Version 16 이하에서는 같은 통계 일부가 pg_stat_bgwriter에 있으므로 PostgreSQL version과 exporter collector를 맞춥니다.

Archive​

SELECT archived_count,
failed_count,
last_archived_wal,
last_archived_time,
last_failed_wal,
last_failed_time
FROM pg_stat_archiver;

실패 counter가 과거 incident 이후 남아 있을 수 있으므로 현재 누적값보다 일정 구간의 증가량(예: increase(pg_stat_archiver_failed_count[1h]))과 마지막 성공 시각을 봅니다. postgres_exporter의 stat_archiver collector는 failed_count를 pg_stat_archiver_failed_count로 노출하며, 배포한 exporter 버전의 실제 이름은 /metrics에서 확인합니다. Archive 실패가 지속되면 pg_wal capacity를 함께 계산합니다.

Replica lag​

Exporter는 replica에서 다음 값을 제공합니다.

pg_replication_is_replica
pg_replication_lag_seconds
pg_replication_last_replay_seconds

Time lag가 0이어도 primary가 idle한 상태일 수 있고, 마지막 replay age가 커도 받을 WAL이 없는 정상 replica일 수 있습니다. Primary에서 byte 위치를 확인합니다.

SELECT application_name,
client_addr,
state,
sync_state,
pg_size_pretty(pg_wal_lsn_diff(sent_lsn, replay_lsn)) AS replay_gap,
write_lag,
flush_lag,
replay_lag
FROM pg_stat_replication;

Replication slot​

SELECT slot_name,
slot_type,
active,
wal_status,
safe_wal_size,
pg_size_pretty(
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)
) AS retained_wal
FROM pg_replication_slots;

Inactive slot과 retained WAL이 동시에 증가하면 disk exhaustion 위험이 있습니다. Slot이 inactive라는 사실만으로 삭제하지 말고 consumer와 복구 전략을 확인합니다.

진단 순서​

  1. 사용자 쓰기 latency와 error 확인
  2. WAL 생성률과 pg_wal 크기 확인
  3. Requested checkpoint와 sync time 확인
  4. Node volume latency/throughput/queue 확인
  5. Archive 성공과 slot retained WAL 확인
  6. Sender/receiver/replay 위치로 lag 단계를 분리

참고: PostgreSQL WAL statistics, Streaming replication monitoring