본문으로 건너뛰기

4.2 DBA를 위한 PromQL

PromQL은 저장된 sample을 운영 질문으로 바꾸는 언어입니다. PostgreSQL에서는 현재 상태를 나타내는 gauge와 누적 통계를 나타내는 counter를 구분하는 것이 출발점입니다.

Raw series부터 확인

복잡한 query를 한 번에 만들지 않습니다.

pg_stat_database_xact_commit

Prometheus Table 화면에서 metric에 실제로 붙은 label과 series 수를 확인한 뒤 filter와 aggregation을 추가합니다.

Counter의 속도와 증가량

초당 transaction은 rate()를 사용합니다.

sum by (instance) (
rate(pg_stat_database_xact_commit{datname!~"template.*"}[5m])
)

최근 30분간 deadlock 발생 건수는 increase()가 읽기 쉽습니다.

sum by (instance) (
increase(pg_stat_database_deadlocks[30m])
)

짧은 window는 빠르게 반응하지만 sample noise가 커지고, 긴 window는 안정적이지만 순간 spike를 늦게 봅니다. Dashboard에는 5분, alert에는 현상의 지속 시간과 scrape interval을 고려한 window를 사용합니다.

비율 계산

Rollback ratio는 실제 transaction rate끼리 나눕니다. Transaction이 없는 구간의 0 / 0은 정의되지 않은 값으로 남깁니다.

sum by (instance) (rate(pg_stat_database_xact_rollback[5m]))
/
sum by (instance) (
rate(pg_stat_database_xact_commit[5m])
+ rate(pg_stat_database_xact_rollback[5m])
)

분자와 분모의 label 집합이 같아야 합니다. 한쪽은 instance, datname, 다른 쪽은 instance로 집계하면 vector matching이 실패하거나 예상치 못한 결과를 만듭니다.

현재값과 시간 범위

Connection 수는 gauge이므로 현재값을 그대로 집계합니다.

sum by (instance) (
pg_stat_database_numbackends{datname!~"template.*"}
)

최근 한 시간의 최고 connection은 다음과 같습니다.

max_over_time(
sum by (instance) (
pg_stat_database_numbackends{datname!~"template.*"}
)[1h:1m]
)

Subquery는 유용하지만 계산량이 큽니다. Dashboard에서 반복 사용한다면 recording rule로 미리 계산합니다.

Top query ID

topk(10,
sum by (instance, datname, queryid) (
rate(pg_stat_statements_seconds_total[5m])
)
)

topk 결과는 선택한 시간 범위의 매 시점마다 구성원이 바뀔 수 있습니다. Grafana legend가 복잡하다면 먼저 database나 instance를 변수로 좁힙니다.

Missing data 처리

metric == 0과 metric 자체가 없는 것은 다릅니다. Exporter가 collector를 비활성화했거나 scrape가 끊기면 series가 사라집니다.

absent(pg_up{instance="db-a:5432"})

Availability alert는 up == 0, pg_up == 0, absent(pg_up)을 목적에 맞게 구분합니다. 모든 조건을 하나의 alert로 합치면 runbook이 모호해집니다.

Offset으로 과거와 비교

sum by (instance) (rate(pg_stat_database_xact_commit[5m]))
/
sum by (instance) (rate(pg_stat_database_xact_commit[5m] offset 7d))

요일별 패턴이 비슷한 서비스에서는 지난주 대비 변화를 볼 수 있습니다. 지난주에 배포나 장애가 있었다면 기준선이 오염되므로 business calendar와 변경 이력을 함께 봅니다.

Counter/Gauge/Missing 상태에 따라 PromQL 함수를 선택하는 기준

Query 작성 원칙

  • Counter에는 먼저 rate()increase()를 적용한 뒤 집계합니다.
  • Gauge에는 의미 없는 rate()를 적용하지 않습니다.
  • 분자와 분모의 label을 맞춥니다.
  • Table에서 series 수를 확인한 뒤 Graph로 이동합니다.
  • 빈 결과를 0으로 바꾸기 전에 missing의 의미를 정합니다.
  • 반복적이고 무거운 query는 recording rule로 옮깁니다.

참고: Prometheus Querying basics, PromQL functions