すべてのプロダクト
Search
ドキュメントセンター

PolarDB:CPU 使用率が高い場合のトラブルシューティング

最終更新日:Jun 09, 2025

PolarDB for PostgreSQL クラスタの使用中に、CPU 使用率が増加したり、100% に達したりすることがあります。このトピックでは、CPU 使用率が高い場合の一般的な原因、トラブルシューティングの方法、および解決策について説明します。

原因とトラブルシューティング方法

ワークロードの増加

CPU 使用率が急上昇する最も一般的な理由は、ワークロードの増加によってデータベースの計算リソースの消費量が増えることです。

トラブルシューティング方法

次の方法を使用して、現在のデータベースのアクティブな接続数が通常よりも多いかどうかを確認できます。

  • データベースに監視システムが用意されている場合は、チャートのアクティブな接続数の変化を確認します。

  • データベースに監視システムが用意されていない場合は、データベースに接続し、次の文を実行してアクティブな接続数を取得します。

    SELECT COUNT(*) FROM pg_stat_activity WHERE state NOT LIKE 'idle';
    説明

    • pg_stat_activity は、PolarDB for PostgreSQL の組み込みシステムビューです。ビューによって返される各行は、実行中の PolarDB for PostgreSQL プロセスです。PolarDB for PostgreSQLPolarDB for PostgreSQL

    • state は、プロセスの現在の状態を示します。有効値:

      • active: プロセスはクエリを実行しています。

      • idle: プロセスはアイドル状態で、クライアントからの新しいコマンドを待機しています。

      • idle in transaction: プロセスはトランザクション中ですが、クエリは実行していません。

      • idle in transaction (aborted): プロセスはトランザクション中にあり、文にエラーがあります。

      • fastpath function call: プロセスは高速パス関数を実行しています。

      • disabled: プロセスでは、ステータス取得機能が無効になっています。

    上記のコマンドは、アイドル状態ではないすべてのプロセスの数をクエリできます。これは、CPU リソースを消費する可能性のあるアクティブな接続の数です。データベースのアクティブな接続数が通常よりも多い場合、CPU 使用率が高いのはワークロードの増加が原因です。

低速なクエリ

CPU 使用率が増加してもアクティブな接続数が正常範囲内にある場合は、パフォーマンスの低い低速なクエリが複数発生している可能性があります。これらの低速なクエリは、長時間にわたって多くの CPU を消費し、CPU 使用率の増加につながる可能性があります。

PolarDB for PostgreSQL は、スロークエリログ機能を提供します。log_min_duration_statement よりも実行時間が長い SQL 文は、スロークエリログに記録されます。ただし、CPU 使用率が 100% に近い場合、システムがフリーズし、すべての SQL 文の実行が遅くなります。そのため、スロークエリログのエントリ数が多くなり、トラブルシューティングが複雑になる可能性があります。

トラブルシューティング方法

実行時間の長い低速なクエリを検出する

pg_stat_statements 拡張機能は、最適化フェーズと実行フェーズ中にデータベースサーバー上のすべての SQL 文の統計情報を記録できます。

この拡張機能は共有メモリを使用するため、拡張機能名は shared_preload_libraries パラメーターに追加されます。

説明

現在のデータベースに pg_stat_statements 拡張機能が作成されていない場合は、次の文を実行して拡張機能を作成します。この拡張機能によって提供される関数とビューもこのプロセスに登録されます。

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
  1. pg_stat_statements 拡張機能とデータベースは、統計情報の累積を続けます。CPU 使用率が高い問題をトラブルシューティングするには、データベースと拡張機能の既存の統計情報をすべてクリアしてから、統計情報の収集を開始する必要があります。

    -- 現在のデータベースの既存の統計情報をすべてクリアします。
    SELECT pg_stat_reset();
    -- pg_stat_statements 拡張機能によって収集された既存の統計情報をすべてクリアします。
    SELECT pg_stat_statements_reset();
  2. データベースと拡張機能が十分な統計情報を収集するまで、1 ~ 2 分待ちます。

  3. 統計情報が収集されたら、次の文を実行して、実行時間が上位 5 つの SQL 文をクエリします。

    SELECT * FROM pg_stat_statements ORDER BY total_plan_time DESC LIMIT 5;
    SELECT * FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;

バッファー読み取り回数が多い低速なクエリを検出する

テーブルにインデックスが作成されておらず、テーブルでポイントクエリが頻繁に実行される場合は、フルスキャンが必要になります。すべてのレコードは、指定された条件を使用してメモリ内でフィルタリングされるため、CPU 使用率が大幅に増加します。

次の文を実行して、pg_stat_statements 拡張機能の統計情報に基づいて、バッファー読み取り回数が多い上位 5 つの SQL 文をクエリします。

SELECT * FROM pg_stat_statements
ORDER BY shared_blks_hit + shared_blks_read DESC
LIMIT 5;

また、PolarDB for PostgreSQL の組み込みシステムビュー pg_stat_user_tables の統計情報に基づいて、フルスキャン回数が多いテーブルをクエリすることもできます。PolarDB for PostgreSQL

次の文を実行して、約 100,000 個のタプルを持つテーブルからフルスキャンで取得されたタプルの数が上位 5 つのテーブルをクエリします。

SELECT * FROM pg_stat_user_tables
WHERE n_live_tup > 100000 AND seq_scan > 0
ORDER BY seq_tup_read DESC
LIMIT 5;

非常に長い時間が経過しても終了しない低速なクエリを検出する

組み込みビュー pg_stat_activity を使用して、非常に長い時間が経過しても終了しない SQL 文をクエリできます。これらの SQL 文は、CPU 使用率が高い原因となる可能性があります。

次の文を実行して、長時間続き終了しない上位 5 つの SQL 文をクエリします。

SELECT
    *,
    extract(epoch FROM (NOW() - xact_start)) AS xact_stay,
    extract(epoch FROM (NOW() - query_start)) AS query_stay
FROM pg_stat_activity
WHERE state NOT LIKE 'idle%'
ORDER BY query_stay DESC
LIMIT 5;

次の文を実行し、前述のフルスキャンが多いテーブルを考慮して、10 秒以上かかる低速クエリを取得します。

SELECT * FROM pg_stat_activity
WHERE
    state NOT LIKE 'idle%' AND
    query ILIKE '%Table name%' AND
    NOW() - query_start > interval '10s';

解決策

  • 予期しない少数の SQL 文が非常に高い CPU リソースを消費している場合は、バックエンドプロセスにシグナルを送信して SQL 文を中断できます。CPU 使用率は正常に戻ります。PID(pg_stat_activity ビューの pid 列)をパラメーターとして使用する次の文を実行して、SQL 文を中断します。

    SELECT pg_cancel_backend(pid);
    SELECT pg_terminate_backend(pid);
  • 時間のかかる SQL 文が必要な場合は、それらを最適化する必要があります。このような SQL 文に関係するテーブルをサンプリングし、その統計情報を更新して、オプティマイザーがより良い実行計画を生成できるようにすることができます。

    説明

    サンプリングは CPU リソースを消費します。オフピーク時にテーブルをサンプリングすることをお勧めします。

    ANALYZE <Table name>;
  • 頻繁なフルスキャンが必要なテーブルの場合は、よく使用されるフィルター列にインデックスを作成し、フルスキャンでインデックスを使用して、メモリに入る前にレコードがフィルタリングされない場合に非常に高くなる可能性のある CPU 使用率を削減できます。