클라우드 관리형 PostgreSQL

RDS, Aurora, Cloud SQL, Azure Database와 같이 확장을 설치할 수 없는 환경에서 사용 가능한 세 가지 경로인 클라이언트 스팬, 쿼리 통계 메트릭, 로그를 설명합니다.

관리형 서비스는 shared_preload_libraries에 서드파티 확장을 등록하는 것을 허용하지 않습니다. 따라서 pg_tracing을 설치할 수 없으며, 데이터베이스 로그 파일에도 접근할 수 없습니다. 사용할 수 있는 경로는 애플리케이션이 생성하는 스팬, 클라이언트 접속으로 조회하는 쿼리 통계, 제공자가 자체 채널로 내보내는 로그 세 가지입니다.

postgres-telemetry

확장을 사용할 수 없는 이유

pg_tracing은 서버 시작 시점에 사전 로드되어야 하는 C 확장입니다. AWS RDS·Aurora, Google Cloud SQL, Azure Database for PostgreSQL은 모두 사전 로드 대상을 제공자가 검증한 목록으로 제한하며, pg_tracing은 어느 목록에도 포함되어 있지 않습니다. 파라미터 그룹이나 데이터베이스 플래그로 우회할 수 있는 제약이 아닙니다.

데이터베이스 로그 역시 동일합니다. 파일 시스템이 노출되지 않으므로 로그 파일을 직접 수집하는 방식은 사용할 수 없습니다.

1. 클라이언트 스팬

가장 먼저 확보해야 할 경로이며, 추가 인프라가 필요하지 않습니다. Sophonz 백엔드 SDK는 데이터베이스 클라이언트를 계측하여 쿼리마다 스팬을 생성합니다. 스팬에는 쿼리문, 대상 데이터베이스, 접속 대상, 소요 시간이 포함되며, 해당 쿼리를 발생시킨 API 요청 및 화면·사용자 세션과 동일한 트레이스로 연결됩니다.

SQLCommenter를 함께 활성화하면 쿼리 텍스트에 traceparent가 주석으로 포함되어 데이터베이스까지 전달됩니다. 기본값으로 켜져 있지 않으므로 설정이 필요합니다. 관리형 환경에는 이 주석을 해석하여 스팬을 생성하는 확장이 없으나, 주석 자체는 제공자 로그에 기록됩니다. 이후 로그를 수집하면 이 값을 기준으로 트레이스와 결합할 수 있습니다.

NOTE — 관리형 환경에서 확보되지 않는 정보

클라이언트 스팬만으로도 어떤 쿼리에 얼마의 시간이 소요되었는지는 정확히 확인할 수 있습니다. 확보할 수 없는 것은 그 시간이 어느 실행계획 노드에서 소비되었는지에 대한 정보입니다. 느린 쿼리를 식별하는 데에는 제약이 없으며, 원인을 규명하는 단계만 확보되지 않습니다.

2. 쿼리 통계 메트릭

pg_stat_statements는 제공자가 지원하는 확장이며, 수집기가 일반 클라이언트로 접속하므로 관리형 환경에서도 동일하게 동작합니다. 쿼리별 호출 수, 총 실행 시간, 평균, 반환 행 수를 주기적으로 조회하여 메트릭으로 변환합니다.

개별 요청을 설명하지는 않습니다. 대신 배포 전후로 평균 실행 시간이 증가한 쿼리, 호출 수가 급증한 쿼리를 확인할 수 있습니다. 성능 회귀 감지에는 트레이스보다 이 경로가 적합합니다.

활성화

세 제공자 모두 확장을 지원하지만, 활성화 위치가 다릅니다.

제공자활성화 방법
AWS RDS · Aurora파라미터 그룹의 shared_preload_libraries에 추가한 후 재부팅
Google Cloud SQL데이터베이스 플래그로 추가한 후 재시작
Azure Database for PostgreSQL서버 파라미터로 추가한 후 재시작

이후 대상 데이터베이스에서 확장을 생성합니다.

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

수집 설정

수집기의 sqlquery 리시버가 읽기 전용 계정으로 접속하여 주기적으로 조회합니다.

collector config
receivers:
  sqlquery/postgres:
    driver: postgres
    datasource: "host=${env:PG_HOST} port=5432 user=${env:PG_USER} password=${env:PG_PASSWORD} dbname=postgres sslmode=require"
    collection_interval: 60s
    queries:
      - sql: >
          SELECT queryid::text AS queryid,
                 calls,
                 mean_exec_time
          FROM pg_stat_statements
          ORDER BY total_exec_time DESC
          LIMIT 200
        metrics:
          - metric_name: postgresql.query.calls
            value_column: calls
            attribute_columns: [queryid]
            value_type: int
            data_type: sum
            monotonic: true
            aggregation: cumulative
          - metric_name: postgresql.query.mean_time
            value_column: mean_exec_time
            attribute_columns: [queryid]
            value_type: double
            data_type: gauge
            unit: ms

상위 항목으로 제한하는 이유는 카디널리티 때문입니다. pg_stat_statements는 수천 개의 항목을 포함할 수 있으며, 이를 모두 메트릭으로 변환하면 쿼리마다 하나의 시계열이 생성됩니다.

queryid는 애플리케이션 스팬에도 부여할 수 있으므로, 메트릭에서 이상 징후가 확인된 쿼리를 동일한 ID로 트레이스에서 조회할 수 있습니다.

CAUTION — 수집기 빌드 확인이 필요합니다

sqlquery 리시버는 Sophonz 수집기 기본 배포판에 포함되어 있지 않습니다. 자체 호스팅 환경에서 활성화하거나 관리형 환경에서 사용하려면 문의해 주세요.

3. 데이터베이스 로그

가장 넓은 속성 집합을 제공하지만 파이프라인 구성 부담이 가장 큽니다. 관리형 서비스는 로그를 파일이 아니라 자체 채널로 내보냅니다.

제공자로그 도착지
AWS RDS · AuroraCloudWatch Logs
Google Cloud SQLCloud Logging
Azure Database for PostgreSQLAzure Monitor

먼저 데이터베이스에서 구조화 로깅을 활성화합니다. JSON 형식으로 출력해야 파싱이 안정적입니다.

log_destination = jsonlog
log_min_duration_statement = 500
log_line_prefix = ''

log_min_duration_statement는 기록 임계값입니다. 0으로 설정하면 모든 문장이 기록되므로, 운영 트래픽이 있는 데이터베이스에서는 로그량이 과도해집니다.

이후 수집기가 제공자 채널에서 로그를 수집합니다. AWS의 경우 awscloudwatch 리시버가 로그 그룹을 구독합니다. 이 경로에서 확보되는 속성은 데이터베이스명, 접속 사용자, 클라이언트 주소, 트랜잭션 ID, 백엔드 유형이며, 오류·락·체크포인트와 같이 스팬으로 표현되지 않는 이벤트도 포함됩니다.

CAUTION — 수집기 빌드 확인이 필요합니다

로그 경로에 필요한 리시버와 파싱 프로세서도 기본 배포판에는 포함되어 있지 않습니다. 도입 시 함께 구성합니다.

권장 적용 순서

세 경로를 동시에 적용할 필요는 없습니다. 다음 순서를 권장합니다.

  1. 클라이언트 스팬 — SDK를 적용하면 즉시 확보됩니다. 대부분의 느린 쿼리는 이 단계에서 확인됩니다.
  2. 쿼리 통계 메트릭 — 확장 활성화와 읽기 전용 계정만 필요합니다. 성능 회귀 감지가 목적이라면 이 단계까지가 가장 효율적입니다.
  3. 로그 — 감사 요건이 있거나, 오류와 락을 함께 확인해야 하는 경우에 추가합니다.

실행계획 수준의 정보가 반드시 필요한 경우, 남은 선택지는 데이터베이스를 직접 운영하는 것입니다. 자체 운영 PostgreSQL을 참고하세요.