본문 바로가기
WIKI 기술 지식 베이스

Supabase Self-Hosted용 데이터베이스 모니터링 설정

원문 보기 위키 갱신

Database Monitoring은 Supabase 데이터베이스에 대한 깊은 가시성을 제공해요. 쿼리 메트릭, 쿼리 샘플, 실행 계획(explain plan), 데이터베이스 상태, 장애 조치(failover), 이벤트까지 한눈에 볼 수 있어요.

Agent가 읽기 전용 사용자로 데이터베이스에 로그인해서 텔레메트리(telemetry)를 직접 수집합니다. Supabase 데이터베이스에서 Database Monitoring을 활성화하려면 다음 설정을 순서대로 진행해요.

  1. Agent에 데이터베이스 접근 권한 부여
  2. Agent 설치

출처: 문서

본문

시작하기 전에

{% dl %}

{% dt %} 지원되는 PostgreSQL 버전 {% /dt %}

{% dd %} 9.6, 10, 11, 12, 13, 14, 15, 16, 17 {% /dd %}

{% dt %} 지원되는 Agent 버전 {% /dt %}

{% dd %} 7.69.1+ {% /dd %}

{% dt %} 성능 영향 {% /dt %}

{% dd %} Database Monitoring의 기본 Agent 설정은 보수적이지만, 수집 간격이나 쿼리 샘플링 비율 같은 설정은 필요에 맞게 조정할 수 있어요. 대부분의 워크로드에서 Agent는 데이터베이스의 쿼리 실행 시간의 1% 미만, CPU의 1% 미만을 차지합니다. Database Monitoring은 기본 Agent 위에서 통합(integration)으로 실행돼요 (벤치마크 참고). {% /dd %}

{% dt %} 프록시, 로드 밸런서, 커넥션 풀러 {% /dt %}

{% dd %} Datadog Agent는 모니터링 대상 호스트에 직접 연결해야 해요. 자체 호스팅 데이터베이스라면 127.0.0.1 또는 소켓을 권장해요. Agent는 프록시, 로드 밸런서, 또는 Supabase의 Dedicated Pooler(pgbouncer)나 Session Pooler(Supavisor) 같은 커넥션 풀러를 통해 데이터베이스에 연결하면 안 됩니다. 실행 중에 Agent가 다른 호스트에 연결하면(장애 조치, 로드 밸런싱 등) 두 호스트 간의 통계 차이를 계산하므로 부정확한 메트릭이 만들어져요. {% /dd %}

{% dt %} 데이터 보안 고려 사항 {% /dt %}

{% dd %} Agent가 데이터베이스에서 수집하는 데이터와 안전하게 보호하는 방법에 대해서는 민감 정보를 참고해요. {% /dd %}

{% /dl %}

Agent 접근 권한 부여

Datadog Agent는 통계와 쿼리를 수집하려면 데이터베이스 서버에 대한 읽기 전용 접근이 필요해요.

Supabase가 복제된 경우 기본(primary) 데이터베이스 서버(작성자/writer)에서 다음 SQL 명령을 실행하세요. Agent가 연결할 데이터베이스 서버의 Supabase 데이터베이스를 선택해요. Agent는 연결한 데이터베이스와 무관하게 서버의 모든 데이터베이스에서 텔레메트리를 수집할 수 있으므로 기본 postgres 데이터베이스를 사용하는 게 좋아요. Agent가 해당 데이터베이스에 고유한 데이터에 대한 커스텀 쿼리를 실행해야 하는 경우에만 다른 데이터베이스를 선택하세요.

선택한 데이터베이스에 수퍼유저(또는 충분한 권한이 있는 사용자)로 연결하세요. 예를 들어 선택한 데이터베이스가 postgres라면 postgres 사용자로 연결해요.

Supabase의 SQL Editor 탭으로 이동해서 다음을 실행하세요:

CREATE USER datadog WITH password '<PASSWORD>';

{% tab title="Postgres ≥ 15" %} datadog 사용자에게 관련 테이블 권한을 부여하세요:

ALTER ROLE datadog INHERIT;

모든 데이터베이스에 다음 스키마를 생성하세요:

CREATE SCHEMA datadog;
GRANT USAGE ON SCHEMA datadog TO datadog;
GRANT USAGE ON SCHEMA public TO datadog;
GRANT USAGE ON SCHEMA extensions TO datadog;
GRANT pg_monitor TO datadog;

또한 Supabase 프로젝트에서 pg_stat_statements 확장이 활성화되어 있는지 확인하세요. {% /tab %}

{% tab title="Postgres ≥ 10" %} 모든 데이터베이스에 다음 스키마를 생성하세요:

CREATE SCHEMA datadog;
GRANT USAGE ON SCHEMA datadog TO datadog;
GRANT USAGE ON SCHEMA public TO datadog;
GRANT USAGE ON SCHEMA extensions TO datadog;
GRANT pg_monitor TO datadog;

또한 Supabase 프로젝트에서 pg_stat_statements 확장이 활성화되어 있는지 확인하세요. {% /tab %}

{% alert level="info" %} 추가 테이블을 쿼리해야 하는 데이터 수집이나 커스텀 메트릭의 경우, 해당 테이블에 대한 SELECT 권한을 datadog 사용자에게 부여해야 할 수 있어요. 예: grant SELECT on <TABLE_NAME> to datadog;. 자세한 내용은 PostgreSQL 커스텀 메트릭 수집을 참고해요. {% /alert %}

Agent가 실행 계획을 수집할 수 있도록 모든 데이터베이스에 다음 함수를 생성하세요.

CREATE OR REPLACE FUNCTION datadog.explain_statement(
   l_query TEXT,
   OUT explain JSON
)
RETURNS SETOF JSON AS
$$
DECLARE
curs REFCURSOR;
plan JSON;

BEGIN
   OPEN curs FOR EXECUTE pg_catalog.concat('EXPLAIN (FORMAT JSON) ', l_query);
   FETCH curs INTO plan;
   CLOSE curs;
   RETURN QUERY SELECT plan;
END;
$$
LANGUAGE 'plpgsql'
RETURNS NULL ON NULL INPUT
SECURITY DEFINER;

컬럼 통계 함수 생성

Agent가 pg_stats에서 컬럼 수준 테이블 통계를 수집할 수 있도록 모든 데이터베이스에 다음 함수를 생성하세요:

CREATE OR REPLACE FUNCTION datadog.column_statistics()
RETURNS TABLE (
    schemaname name, tablename name, attname name,
    n_distinct real, avg_width integer, null_frac real,
    inherited boolean, correlation real, most_common_freqs real[]
) AS
$$ SELECT schemaname, tablename, attname, n_distinct, avg_width, null_frac,
          inherited, correlation, most_common_freqs
          FROM pg_catalog.pg_stats
          WHERE schemaname NOT IN ('pg_catalog', 'information_schema'); $$
LANGUAGE sql
SECURITY DEFINER
SET search_path = pg_catalog, pg_temp;

함수가 생기면 Postgres 인스턴스 설정에서 수집을 활성화하세요:

instances:
  - dbm: true
    ...
    collect_column_statistics:
      enabled: true

튜닝 옵션은 고급 설정을 참고해요.

비밀번호 안전하게 보관

Vault 같은 시크릿 관리 소프트웨어로 비밀번호를 보관하세요. 그러면 Agent 설정 파일에서 ENC[<SECRET_NAME>] 형식으로 참조할 수 있어요. 예를 들어 ENC[datadog_user_database_password]처럼요. 자세한 내용은 Secrets Management를 참고해요.

이 페이지의 예제는 비밀번호가 저장된 시크릿 이름으로 datadog_user_database_password를 사용해요. 비밀번호를 평문으로도 참조할 수 있지만 권장하지 않아요.

검증

권한이 올바른지 확인하려면 datadog 사용자로 데이터베이스에 연결해서 다음 명령을 실행하세요. 예를 들어 데이터베이스가 postgres라면 psql로 datadog 사용자로 연결해서 실행해요:

psql -h {SUPABASE_HOST} -U datadog postgres -A \
  -c "select * from pg_stat_database limit 1;" \
  && echo -e "\e[0;32mPostgres connection - OK\e[0m" \
  || echo -e "\e[0;31mCannot connect to Postgres\e[0m"
psql -h {SUPABASE_HOST} -U datadog postgres -A \
  -c "select * from pg_stat_activity limit 1;" \
  && echo -e "\e[0;32mPostgres pg_stat_activity read OK\e[0m" \
  || echo -e "\e[0;31mCannot read from pg_stat_activity\e[0m"
psql -h {SUPABASE_HOST} -U datadog postgres -A \
  -c "select * from pg_stat_statements limit 1;" \
  && echo -e "\e[0;32mPostgres pg_stat_statements read OK\e[0m" \
  || echo -e "\e[0;31mCannot read from pg_stat_statements\e[0m"

비밀번호를 묻는 메시지가 나오면 datadog 사용자를 위해 만든 비밀번호를 사용하세요.

Agent 설치

Datadog Agent를 설치하면 Supabase에서 Database Monitoring에 필요한 Postgres 체크도 함께 설치돼요. Agent를 아직 설치하지 않았다면 Agent 설치 안내를 참고해요. 그런 다음 여기로 돌아와서 사용 중인 설치 방법에 대한 안내를 계속 따라가세요.

{% alert level="info" %} Supabase의 기본 직접 연결 문자열은 IPv6 네트워크에서만 유효해요. 이 방법으로 Agent를 Supabase 인스턴스에 연결하려면 Agent를 실행하는 머신에서 IPv6이 활성화되어 있어야 해요. 자세한 내용은 클라우드 프로바이더 문서를 참고하세요. Pro 요금제 이상의 Supabase 인스턴스는 IPv4 주소를 애드온으로 지원해요. {% /alert %}

Agent의 conf.d/postgres.d/conf.yaml 파일을 편집해 모니터링하려는 Supabase 인스턴스를 지정하세요. 전체 설정 옵션 목록은 샘플 postgres.d/conf.yaml을 참고해요.

init_config:
instances:
    - dbm: true
      host: <SUPABASE_INSTANCE_ENDPOINT>
      port: 5432
      username: datadog
      password: 'ENC[datadog_user_database_password]'

      ## Optional: Connect to a different database if needed for `custom_queries`
      # dbname: '<DB_NAME>'

참고: 비밀번호에 특수 문자가 포함되어 있다면 작은따옴표로 감싸세요.

변경 사항을 적용하려면 Agent를 재시작하세요.

검증

Agent의 status 하위 명령을 실행하고 Checks 섹션에서 postgres를 찾아보세요. 또는 Databases 페이지를 방문해 바로 시작해도 돼요!

예제 Agent 설정

Supavisor의 session pooler 사용

데이터베이스에 프록시를 통하지 않고 직접 연결하는 것을 권장하지만, 위 옵션을 사용할 수 없다면 Agent를 Supabase 인스턴스에 연결할 수는 있어요. Supabase 프로젝트에 인스턴스가 하나뿐일 때 가장 잘 동작해요.

Connect 대화 상자에서 프로젝트의 session pooler 연결 문자열을 가져와 Agent 설정 파일에 복사하세요:

init_config:
instances:
    - dbm: true
      host: <SUPABASE_POOLER_ENDPOINT>
      port: 5432
      username: datadog.some-project-id
      password: 'ENC[datadog_user_database_password]'

하나의 Agent가 여러 호스트에 연결

단일 Agent 호스트가 여러 원격 데이터베이스 인스턴스에 연결하도록 설정하는 건 흔한 일이에요 (DBM의 Agent 설치 아키텍처 참조). 여러 호스트에 연결하려면 Postgres 통합 설정에서 호스트마다 항목을 만들어요.

{% alert level="info" %} Datadog는 하나의 Agent로 최대 30개의 데이터베이스 인스턴스를 모니터링할 것을 권장해요. 벤치마크에 따르면 t4g.medium EC2 인스턴스(2 CPU, 4GB RAM)에서 실행 중인 Agent 하나가 RDS db.t3.medium 인스턴스(2 CPU, 4GB RAM) 30개를 성공적으로 모니터링할 수 있어요. {% /alert %}

init_config:
instances:
  - dbm: true
    host: example-service-primary.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    tags:
      - 'env:prod'
      - 'team:team-discovery'
      - 'service:example-service'
  - dbm: true
    host: example-service–replica-1.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    tags:
      - 'env:prod'
      - 'team:team-discovery'
      - 'service:example-service'
  - dbm: true
    host: example-service–replica-2.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    tags:
      - 'env:prod'
      - 'team:team-discovery'
      - 'service:example-service'
    [...]

데이터베이스 호스트의 여러 데이터베이스 모니터링

database_autodiscovery 옵션을 사용하면 Agent가 호스트의 모든 데이터베이스를 발견해 모니터링할 수 있어요. include 또는 exclude 필드로 발견할 데이터베이스 범위를 좁힐 수 있어요. 자세한 내용은 postgres.d/conf.yaml 샘플을 참고해요.

init_config:
instances:
  - dbm: true
    host: example-service-primary.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    database_autodiscovery:
      enabled: true
      # Optionally, set the include field to specify
      # a set of databases you are interested in discovering
      include:
        - mydb.*
        - example.*
    tags:
      - 'env:prod'
      - 'team:team-discovery'
      - 'service:example-service'

커스텀 쿼리 실행

커스텀 메트릭을 수집하려면 custom_queries 옵션을 사용해요. 자세한 내용은 postgres.d/conf.yaml 샘플을 참고해요.

init_config:
instances:
  - dbm: true
    host: localhost
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    custom_queries:
    - metric_prefix: employee
      query: SELECT age, salary, hours_worked, name FROM hr.employees;
      columns:
        - name: custom.employee_age
          type: gauge
        - name: custom.employee_salary
           type: gauge
        - name: custom.employee_hours
           type: count
        - name: name
           type: tag
      tags:
        - 'table:employees'

여러 데이터베이스의 relation 메트릭 모니터링

relation 메트릭(예: postgresql.seq_scans, postgresql.dead_rows, postgresql.index_rows_read, postgresql.table_size)을 수집하려면 Agent가 각 데이터베이스에 연결하도록 설정해야 해요 (기본적으로 Agent는 postgres 데이터베이스에만 연결해요).

모든 데이터베이스에서 DBM 텔레메트리를 수집하도록 단일 "DBM" 인스턴스를 지정하세요. 각 데이터베이스 이름을 지정하지 않으려면 database_autodiscovery 옵션을 사용해요.

init_config:
instances:
  # This instance is the "DBM" instance. It will connect to the
  # all logical databases, and send DBM telemetry from all databases
  - dbm: true
    host: example-service-primary.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    database_autodiscovery:
      enabled: true
      exclude:
        - ^users$
        - ^inventory$
    relations:
      - relation_regex: .*
  # This instance only collects data from the `users` database
  # and collects relation metrics from tables prefixed by "2022_"
  - host: example-service-primary.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    dbname: users
    dbstrict: true
    relations:
      - relation_regex: 2022_.*
        relkind:
          - r
          - i
  # This instance only collects data from the `inventory` database
  # and collects relation metrics only from the specified tables
  - host: example-service-primary.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    dbname: inventory
    dbstrict: true
    relations:
      - relation_name: products
      - relation_name: external_seller_products

스키마 수집

이 기능을 활성화하려면 collect_schemas 옵션을 사용해요. 각 논리적 데이터베이스에 연결하도록 Agent도 설정해야 해요.

각 논리적 데이터베이스를 지정하지 않으려면 database_autodiscovery 옵션을 사용해요. 자세한 내용은 postgres.d/conf.yaml 샘플을 참고해요.

init_config:
# This instance only collects data from the `users` database
# and collects relation metrics only from the specified tables
instances:
  - dbm: true
    host: example-service-primary.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    dbname: users
    dbstrict: true
    collect_schemas:
      enabled: true
    relations:
      - products
      - external_seller_products
  # This instance detects every logical database automatically
  # and collects relation metrics from every table
  - dbm: true
    host: example-service–replica-1.example-host.com
    port: 5432
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    database_autodiscovery:
      enabled: true
    collect_schemas:
      enabled: true
    relations:
      - relation_regex: .*

프록시를 통한 호스트 연결

Cloud SQL Auth proxy 같은 프록시를 통해 Agent가 연결해야 한다면 모든 텔레메트리의 호스트네임이 데이터베이스 인스턴스가 아닌 프록시로 태그돼요. reported_hostname 옵션으로 Agent가 감지하는 호스트네임을 커스텀 오버라이드하세요.

init_config:
instances:
  - dbm: true
    host: localhost
    port: 5000
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    reported_hostname: example-service-primary
  - dbm: true
    host: localhost
    port: 5001
    username: datadog
    password: 'ENC[datadog_user_database_password]'
    reported_hostname: example-service-replica-1

문제 해결

통합과 Agent를 설명한 대로 설치·설정했는데도 예상대로 동작하지 않는다면 문제 해결을 참고해요.

더 알아보기 (Learn more)

추가로 도움이 되는 문서, 링크, 아티클: