高度な Query Insights を使用してクエリのパフォーマンスをモニタリングする

ドキュメントのバージョンを選択してください。

高度な Query Insights を使用すると、AlloyDB Omni データベースのクエリ パフォーマンスの問題を検出、診断、防止できます。正規化されたクエリ統計、待機イベント、クライアント IP アドレス、タグ、インスタンス負荷などのデータベース テレメトリーをキャプチャし、過去の指標を 30 日間保持します。

高度な Query Insights を使用すると、次のタスクを実行できます。

  • 実行時間、I/O 時間、待機時間、共有バッファ アクティビティ、行数を分析して、レイテンシが高く、リソースを大量に消費するクエリを特定します。
  • 低速なクエリと待機イベントおよび待機イベント クラスを関連付けて、ボトルネックのトラブルシューティングを行います。
  • SQLCommenter メタデータでクエリにタグを付けて、クエリのパフォーマンスを特定のアプリケーション コンポーネントにトレースします。
  • アクティブなクエリとオープン トランザクションをリアルタイムでモニタリングし、問題のあるセッションを停止します。

始める前に

高度な Query Insights を有効にする前に、次の要件を確認してください。

  • コンテナでスタンドアロン AlloyDB Omni インスタンスを実行している。

  • データベース インスタンスへの postgres スーパーユーザー アクセス権と、コンテナを再起動するための管理者権限がある。

  • alloydbadmin データベースがインスタンスに存在している。AlloyDB Omni は、初期化時にデフォルトでこのデータベースを作成します。

Query Insights を有効にする

高度な Query Insights を有効にする手順は次のとおりです。

  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 データベースに高度な Query Insights 拡張機能を作成します。

    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 では、高度な Query Insights が、次のディメンションと機能にわたって、データベース テレメトリーを alloydbadmin データベースの SQL テーブル、ビュー、関数に記録します。

  • クエリ: クエリ レイテンシが増加したときに、低速またはリソース消費量の多い SQL ステートメントを特定するために使用します。
  • 待機イベントタイプ: CPU、ディスク I/O、ロックの競合がワークロードのボトルネックの原因かどうかを判断するために使用します。
  • 待機イベント: DataFileRead や WALWrite など、クエリの実行を遅延させる特定の PostgreSQL 待機イベントを特定するために使用します。
  • データベース: 論理データベース間のリソース消費量を比較し、共有インスタンスで高負荷のデータベースを分離するために使用します。
  • ユーザーとクライアント IP アドレス: クエリ負荷を特定のデータベース ロールまたはクライアント IP アドレスに関連付け、問題のあるアプリケーション クライアントを特定するために使用します。
  • タグ: データベース負荷を、SQLCommenter でタグ付けされた特定のアプリケーション サービス、ルート、ORM アクションに関連付けるために使用します。
  • アクティブなクエリ: ライブ パフォーマンスの急増、ブロックされたトランザクション、長時間実行セッションをリアルタイムで診断するために使用します。

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: 構成する Query Insights のパラメータの名前(google_insights_v2.qi_track_active_queries、google_insights_v2.qi_track_tag、google_insights_v2.qi_track_client_address など)。
  • VALUE: パラメータの新しい値(on など)。

各パラメータの説明、対応するオブザーバビリティ ビュー、各ビューが返す指標と列については、高度な Query Insights のリファレンスをご覧ください。

時間の粒度

各履歴 observability_service_* ビューは、次の 3 つの時間粒度で使用できます。

  • ベースビュー(*_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)値に置き換えます。

高度な Query Insights を無効にする

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;

次のステップ