고급 쿼리 통계를 사용하여 쿼리 성능 모니터링

문서 버전을 선택합니다.

고급 쿼리 통계를 사용하면 AlloyDB Omni 데이터베이스에서 쿼리 성능 문제를 감지, 진단, 방지할 수 있습니다. 정규화된 쿼리 통계, 대기 이벤트, 클라이언트 IP 주소, 태그, 인스턴스 부하를 비롯한 데이터베이스 원격 분석을 캡처하고 30일 동안 이전 측정항목을 보관합니다.

고급 쿼리 통계를 사용하여 다음 작업을 실행할 수 있습니다.

  • 실행 시간, I/O 시간, 대기 시간, 공유 버퍼 활동, 행 수를 분석하여 지연 시간이 길고 리소스 집약적인 쿼리를 식별합니다.
  • 느린 쿼리를 대기 이벤트 및 대기 이벤트 클래스와 상호 연결하여 병목 현상을 해결합니다.
  • SQLCommenter 메타데이터로 쿼리에 태그를 지정하여 쿼리 성능을 특정 애플리케이션 구성요소로 추적합니다. SQLCommenter
  • 활성 쿼리 및 열린 트랜잭션을 실시간으로 모니터링하고 문제가 있는 세션을 중지합니다.

시작하기 전에

고급 쿼리 통계를 사용 설정하기 전에 다음 요구사항을 확인하세요.

  • 컨테이너에서 독립형 AlloyDB Omni 인스턴스를 실행하고 있습니다.

  • 데이터베이스 인스턴스에 대한 postgres 슈퍼유저 액세스 권한과 컨테이너를 다시 시작할 수 있는 관리 액세스 권한이 있습니다.

  • 인스턴스에 alloydbadmin 데이터베이스가 있습니다. AlloyDB Omni는 초기화 중에 이 데이터베이스를 기본적으로 만듭니다.

고급 쿼리 통계 사용 설정

고급 쿼리 통계를 사용 설정하려면 다음 단계를 따르세요.

  1. postgres 슈퍼유저로 postgres 데이터베이스에 연결합니다.

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    CONTAINER_NAME을 AlloyDB Omni 컨테이너 이름(예: my-omni-1)으로 바꿉니다.

  2. shared_preload_libraries에서 로드된 라이브러리를 확인하고, 고급 쿼리 통계를 사전 로드 목록에 추가하고, 확장 프로그램을 사용 설정하고, psql을 종료합니다.

    SHOW shared_preload_libraries;
    ALTER SYSTEM SET shared_preload_libraries = 'LIBRARY_1','LIBRARY_2','google_insights_v2';
    ALTER SYSTEM SET google_insights_v2.enabled = on;
    \q
    

    LIBRARY_1, LIBRARY_2, 추가 기존 라이브러리를 SHOW shared_preload_libraries에서 반환된 라이브러리 이름으로 바꿉니다. 각 개별 라이브러리 항목을 작은따옴표로 묶고(예: 'g_stats','google_columnar_engine','google_insights_v2'), AlloyDB Omni에 필요한 모든 기존 라이브러리를 포함하여 덮어쓰지 않도록 합니다.

  3. AlloyDB Omni 서버를 다시 시작하여 사전 로드 설정을 적용합니다.

    Docker

    docker restart CONTAINER_NAME
    

    Docker

    docker restart CONTAINER_NAME
    

    Podman

    podman restart CONTAINER_NAME
    

    Podman

    podman restart CONTAINER_NAME
    
  4. postgres 슈퍼유저로 alloydbadmin 데이터베이스에 연결합니다.

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    
  5. alloydbadmin 데이터베이스에서 고급 쿼리 통계 확장 프로그램을 만듭니다.

    CREATE EXTENSION IF NOT EXISTS google_insights_v2;
    
  6. 라이브러리가 로드되고, 확장 프로그램이 사용 설정되고, google_insights_v2 확장 프로그램이 alloydbadmin에 설치되어 있는지 확인합니다.

    SHOW shared_preload_libraries;
    SHOW google_insights_v2.enabled;
    SELECT extname, extversion FROM pg_extension WHERE extname = 'google_insights_v2';
    

    shared_preload_libraries에 google_insights_v2가 포함되어 있고, google_insights_v2.enabled가 on을 반환하고, pg_extension이 google_insights_v2의 행을 반환하는지 확인합니다.

측정기준 및 기능 매개변수

AlloyDB Omni에서 고급 쿼리 통계는 다음 측정기준 및 기능 전반에서 alloydbadmin 데이터베이스의 SQL 테이블, 뷰, 함수에 데이터베이스 원격 분석을 기록합니다.

  • 쿼리: 쿼리 지연 시간이 증가할 때 느리거나 리소스 집약적인 SQL 문을 식별하는 데 사용합니다.
  • 대기 이벤트 유형: CPU, 디스크 I/O 또는 잠금 경합이 워크로드 병목 현상을 일으키는지 확인하는 데 사용합니다.
  • 대기 이벤트: 쿼리 실행을 지연시키는 특정 PostgreSQL 대기 이벤트(예: DataFileRead 또는 WALWrite)를 식별하는 데 사용합니다.
  • 데이터베이스: 논리 데이터베이스 간의 리소스 소비를 비교하고 공유 인스턴스에서 부하가 높은 데이터베이스를 격리하는 데 사용합니다.
  • 사용자 및 클라이언트 IP 주소: 쿼리 부하를 특정 데이터베이스 역할 또는 클라이언트 IP 주소에 할당하고 문제가 있는 애플리케이션 클라이언트를 식별하는 데 사용합니다.
  • 태그: SQLCommenter로 태그가 지정된 특정 애플리케이션 서비스, 경로 또는 ORM 작업과 데이터베이스 부하를 상호 연결하는 데 사용합니다. SQLCommenter
  • 활성 쿼리: 실시간으로 실시간 성능 급증, 차단된 트랜잭션, 장기 실행 세션을 진단하는 데 사용합니다.

google_insights_v2.enabled를 on으로 설정하면 AlloyDB Omni는 쿼리, 대기 이벤트 유형, 대기 이벤트, 데이터베이스, 사용자의 측정항목을 자동으로 수집합니다.

데이터베이스 서버를 다시 시작하지 않고 런타임에 google_insights_v2.* 매개변수를 업데이트하려면 ALTER SYSTEM SET를 실행하고 구성을 다시 로드합니다.

ALTER SYSTEM SET PARAMETER_NAME = VALUE;
SELECT pg_reload_conf();

다음을 바꿉니다.

  • PARAMETER_NAME: 구성할 고급 쿼리 통계 매개변수의 이름입니다(예: google_insights_v2.qi_track_active_queries, google_insights_v2.qi_track_tag, google_insights_v2.qi_track_client_address).
  • VALUE: 매개변수의 새 값입니다(예: on).

각 매개변수, 해당 관측 가능성 뷰, 각 뷰가 반환하는 측정항목 및 열에 대한 설명은 고급 쿼리 통계 참조를 확인하세요.

시간 단위

각 이전 observability_service_* 뷰는 세 가지 시간 단위로 제공됩니다.

  • 기본 뷰 (*_view): 15초 플러시 간격입니다. 이러한 뷰를 사용하여 지난 1~6시간 이내에 발생한 최근 급증 또는 사고를 조사합니다.
  • 대략적인 수준 1 뷰 (*_coarse_1_view): 상위 2,000개 쿼리에 대한 5분 집계 간격입니다. 이러한 뷰를 사용하여 6~24시간 동안의 성능 추세를 분석합니다.
  • 대략적인 수준 2 뷰 (*_coarse_2_view): 상위 2,000개 쿼리에 대한 30분 집계 간격입니다. 이러한 뷰를 사용하여 최대 30일 보관 한도까지의 여러 날짜 추세를 분석합니다.

이전 모니터링 가능성 뷰는 total_execution_time, total_wait_time, total_read_time, total_write_time, time_spent를 비롯한 모든 실행, 대기, I/O 시간 열을 마이크로초 단위로 저장합니다.

이전 실적 측정항목 쿼리

alloydbadmin 데이터베이스에 연결하여 이전 모니터링 가능성 뷰에 대해 진단 쿼리를 실행합니다. 자세한 내용은 AlloyDB Omni 실행 및 연결을 참고하세요.

이 섹션의 SQL 문은 측정기준 전반의 일반적인 문제 해결 시나리오에 대한 쿼리 예시입니다. 이러한 예시를 맞춤설정하여 recorded_on 기간 변경, 특정 데이터베이스 또는 역할별 필터링, 여러 날짜 분석을 위한 *_coarse_1_view 및 *_coarse_2_view 쿼리 등 워크로드에 맞게 조정할 수 있습니다.

지연 시간이 긴 쿼리 식별

지난 1시간 동안 총 실행 시간이 가장 긴 상위 10개 정규화된 쿼리를 찾으려면 google_insights_v2.observability_service_query_view에 대해 다음 쿼리 예시를 실행합니다.

SELECT
  query_id,
  database,
  username,
  left(query, 100) AS normalized_query,
  sum(count) AS total_executions,
  sum(total_execution_time) AS total_execution_time_us,
  round((sum(total_execution_time)::numeric / NULLIF(sum(count), 0)), 2) AS avg_execution_time_us,
  sum(total_rows) AS total_rows,
  sum(total_shared_blocks_hit) AS shared_blocks_hit,
  sum(total_shared_blocks_read) AS shared_blocks_read
FROM google_insights_v2.observability_service_query_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY query_id, database, username, left(query, 100)
ORDER BY total_execution_time_us DESC
LIMIT 10;

쿼리별 대기 이벤트 분석

특정 query_id에 가장 많은 대기 시간을 제공하는 대기 이벤트 카테고리 (wait_class) 및 세분화된 대기 이벤트 (wait_event)를 식별하려면 google_insights_v2.observability_service_wait_event_stats_by_query_view에 대해 다음 쿼리 예시를 실행합니다.

SELECT
  query_id,
  database,
  username,
  wait_class,
  wait_event,
  sum(count) AS wait_occurrences,
  sum(time_spent) AS total_wait_time_us
FROM google_insights_v2.observability_service_wait_event_stats_by_query_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
  AND query_id = QUERY_ID
GROUP BY query_id, database, username, wait_class, wait_event
ORDER BY total_wait_time_us DESC;

QUERY_ID를 observability_service_query_view에서 반환하는 query_id 값으로 바꿉니다.

데이터베이스, 사용자, 클라이언트 IP 부하 분석

지난 1시간 동안 논리 데이터베이스 및 데이터베이스 역할 전반에서 총 실행 시간, 대기 시간, 쿼리 볼륨을 비교하려면 google_insights_v2.observability_service_db_load_conn_view에 대해 다음 쿼리 예시를 실행합니다.

SELECT
  database,
  username,
  sum(count) AS total_executions,
  sum(total_execution_time) AS total_execution_time_us,
  sum(total_wait_time) AS total_wait_time_us
FROM google_insights_v2.observability_service_db_load_conn_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY database, username
ORDER BY total_execution_time_us DESC;

google_insights_v2.qi_track_client_address를 사용 설정하면 google_insights_v2.observability_service_client_address_stats_by_query_view에 대해 다음 쿼리 예시를 사용하여 가장 많은 쿼리 시간을 생성하는 연결 클라이언트 IP 주소를 식별할 수도 있습니다.

SELECT
  client_address,
  username,
  database,
  query_id,
  sum(count) AS total_executions,
  sum(time_spent) AS total_time_spent_us
FROM google_insights_v2.observability_service_client_address_stats_by_query_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY client_address, username, database, query_id
ORDER BY total_time_spent_us DESC
LIMIT 10;

태그별 쿼리 성능 추적

google_insights_v2.qi_track_tag가 on으로 설정되어 있고 쿼리에 SQLCommenter 주석이 포함되어 있는 경우 다음 쿼리 예시를 실행하여 애플리케이션 태그 메타데이터별로 실행 시간을 집계합니다. google_insights_v2.observability_service_tag_view를 사용합니다.

SELECT
  application,
  framework_name,
  framework_controller,
  framework_action,
  framework_route,
  database,
  username,
  sum(count) AS total_executions,
  sum(total_execution_time) AS total_execution_time_us,
  round((sum(total_execution_time)::numeric / NULLIF(sum(count), 0)), 2) AS avg_execution_time_us
FROM google_insights_v2.observability_service_tag_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY
  application,
  framework_name,
  framework_controller,
  framework_action,
  framework_route,
  database,
  username
ORDER BY total_execution_time_us DESC
LIMIT 10;

활성 쿼리 모니터링

google_insights_v2.qi_track_active_queries을 on으로 설정하면 alloydbadmin 데이터베이스에서 google_insights_v2.stat_activity 및 google_insights_v2.stat_activity_v3을 쿼리하여 실행 중인 쿼리 및 열린 트랜잭션을 실시간으로 모니터링할 수 있습니다.

이러한 뷰는 백그라운드 작업자 및 alloydbadmin 연결을 제외하면서 활성 클라이언트 연결, 세션 및 트랜잭션 기간, 현재 대기 이벤트를 노출합니다.

활성 세션 및 트랜잭션 기간 쿼리

현재 인스턴스에서 활발하게 실행 중인 쿼리와 가장 오래 실행 중인 트랜잭션을 식별하려면 alloydbadmin에서 다음 쿼리 예시를 실행합니다.

SELECT
  pid AS "Process ID",
  left(normalized_query, 40) AS "Query",
  state AS "Status",
  round(EXTRACT(EPOCH FROM (clock_timestamp() - backend_start))::numeric, 2) AS "Session duration (secs)",
  CASE
    WHEN xact_start IS NOT NULL
    THEN round(EXTRACT(EPOCH FROM (clock_timestamp() - xact_start))::numeric, 2)
    ELSE NULL
  END AS "Transaction duration (secs)",
  CASE
    WHEN query_start IS NOT NULL
    THEN round(EXTRACT(EPOCH FROM (clock_timestamp() - query_start))::numeric, 2)
    ELSE NULL
  END AS "Query duration (secs)",
  COALESCE(wait_event_type, '') AS "Wait event type",
  COALESCE(wait_event, '') AS "Wait event",
  database AS "Database",
  COALESCE(application_name, '') AS "Application name",
  username AS "Username",
  COALESCE(client_addr::text, '') AS "Client address"
FROM google_insights_v2.stat_activity_v3
WHERE state = 'active'
ORDER BY query_start ASC;

장기 실행 쿼리 또는 트랜잭션 중지

google_insights_v2.stat_activity_v3에서 식별된 장기 실행 쿼리 또는 차단된 트랜잭션을 중지하려면 프로세스 ID를 pg_terminate_backend에 전달합니다.

SELECT pg_terminate_backend(PROCESS_ID);

PROCESS_ID를 google_insights_v2.stat_activity_v3에서 반환된 Process ID (pid) 값으로 바꿉니다.

고급 쿼리 통계 사용 중지

AlloyDB Omni 인스턴스를 다시 시작하지 않고 원격 분석 수집을 중지하려면 google_insights_v2.enabled를 off로 설정하고 구성을 다시 로드합니다.

ALTER SYSTEM SET google_insights_v2.enabled = off;
SELECT pg_reload_conf();

alloydbadmin 데이터베이스에서 확장 프로그램 객체와 저장된 이전 데이터를 삭제하려면 alloydbadmin에 연결하고 확장 프로그램을 삭제합니다.

DROP EXTENSION IF EXISTS google_insights_v2 CASCADE;

다음 단계