Amazon RDS または Amazon Aurora PostgreSQL の高い CPU 使用率をトラブルシューティングする方法を教えてください。

最終更新日: 2020 年 6 月 18 日

Amazon Relational Database Service (Amazon RDS) または Amazon Aurora PostgreSQL で、CPU 使用率が高くなる原因を特定し解決するにはどうすればよいですか?

簡単な説明

CPU 使用率が高い場合は、次のツールを組み合わせて原因を特定できます。

この記事では、これらの各ツールを使用して CPU 使用率が高くなる原因を特定する方法について説明します。

解決方法

Amazon CloudWatch メトリクス

CloudWatch メトリクスを使用して、長期間にわたる CPU パターンを識別できます。WriteIOPsReadIOPsReadThroughput、および WriteThroughput のグラフを CPU 使用率と比較して、ワークロードによって高い CPU が発生した時間を調べます。

時間枠を特定したら、DB インスタンスに関連付けられた拡張モニタリングデータを確認できます。1、5、10、15、30、または 60 秒の間隔でデータを収集するように拡張モニタリングを設定できます。これにより、CloudWatch よりも詳細なレベルでデータを収集できます。詳細については、CloudWatch と拡張モニタリングのメトリクスの相違点をご参照ください。

拡張モニタリング

拡張モニタリングはオペレーティングシステム (OS) レベルで確認できます。これは CPU 負荷が高い原因を詳細レベルで識別するのに役立ちます。たとえば、負荷平均、CPU 配分 (system% または nice%)、OS プロセスリストを確認できます。

拡張モニタリングを使用すると、1、5、および 15 分間隔で loadAverageMinute データを確認できます。平均負荷が vCPU の数より大きい場合、インスタンスが高負荷状態にあることを示します。また、負荷平均が DB インスタンスクラスの vCPU 数より少ない場合、CPU スロットリングがアプリケーションのレイテンシーの原因にならない可能性があります。CPU 使用率の原因を診断する際に誤検出を避けるためにも、平均負荷を確認してください。

たとえば、CPU 制限に達する 3 千個のプロビジョンド IOPS を持つ db.m4.2xlarge インスタンスクラスを使用している DB インスタンスがある場合、以下のメトリクス例を確認して、CPU 使用率が高い根本の原因を特定できます。次の例では、インスタンスクラスには 8 個の vCPU が関連付けられています。同じ平均負荷で 170 を超えるということは、測定された時間枠の間にマシンが重い負荷を受けていることを示します。

平均負荷時間 (分)
 
15 170.25
5 391.31
1 596.74
CPU 使用率  
ユーザー (%) 0.71
システム (%) 4.9
Nice (%) 93.92
合計 (%) 99.97

注意: Amazon RDS では、DB インスタンスで実行されている他のタスクよりもワークロードの優先度が高くなります。これらのタスクに優先順位を付けるため、ワークロードタスクにはより高い Nice 値が与えられます。この結果、拡張モニタリングでは Nice% はデータベースに対してワークロードが使用している CPU の量を表します。

拡張モニタリングを有効にした後、DB インスタンスに関連付けられている OS プロセスリストも確認できます。拡張モニタリングでは、CPU とメモリの両方について、上位 50 個のプロセスのみが表示されます。これにより、CPU とメモリの使用量に基づいてパフォーマンスに最大の影響を与えるプロセスを特定できます。

拡張モニタリングの結果を pg_stat_activity の結果とともにクラブすると、クエリのリソース使用状況を特定しやすくなります。

Performance Insights

Amazon RDS Performance Insights を使用して、特定の時間枠に対応する SQL タブを確認した後、データベースの負荷を担当するクエリを特定できます。

ネイティブ PostgreSQL のビューとカタログ

データベースエンジンレベルで問題が発生した場合、リアルタイムで pg_stat_activity または pg_stat_statements を使用することができます。これらは、最も多くトラフィックを送信するマシン、クライアント、IP アドレスをグループ化するのに役立ちます。このデータを使用して、時間の経過に伴う増加、アプリケーションサーバーの増加、またはアプリケーションサーバーがセッションやロックの問題を解決できるかどうかを確認することもできます。詳細については、pg_stat_activity および pg_stat_statements に関する PostgreSQL のドキュメントをご参照ください。pg_stat_statements を有効にするには、既存のカスタムパラメータグループを修正して以下の値を設定します。

  • shared_preload_libraries = pg_stat_statements
  • track_activity_query_size = 2048
  • pg_stat_statements.track = ALL
  • pg_stat_statements.max = 10000

[すぐに適用] を選択して、DB インスタンスを再起動してください。次に、モニタリングするデータベースで以下のようなコマンドを実行します。

注: 次の例では、「デモ」データベースに拡張機能をインストールします。

demo=> select current_database();
current_database
------------------
demo
(1 row)
     
demo=> CREATE EXTENSION pg_stat_statements;

pg_stat_statementsがセットアップされた後、以下の方法のうちの 1 つを使用することによって出力をモニタリングすることができます。

  • total_time でクエリのリストを表示し、どのクエリがデータベースで最も時間を費やしているかを確認します。
SELECT round(total_time*1000)/1000 AS total_time,query
FROM pg_stat_statements
ORDER BY total_time DESC limit 2;
  • 呼び出し数の合計、行数の合計、および返された行数を含むクエリを一覧表示します。
SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
  • 実行ごとにクエリを一覧表示して、時間の経過とともにクエリをサンプリングします。
SELECT query, calls, total_time/calls as avg_time_ms, rows/calls as avg_rows,
temp_blks_read/calls as avg_tmp_read, temp_blks_written/calls as avg_temp_written
FROM pg_stat_statements
WHERE calls != 0
ORDER BY total_time DESC LIMIT 5;

PostgreSQL のログパラメータ

Amazon RDS for PostgreSQL を使用したクエリログを有効化します。次に PostgreSQL のエラーログを確認し、log_min_duration_statement および log_statement パラメータが適切な値に設定されていることを確認します。詳細については、PostgreSQL のドキュメントの Error Reporting and Logging をご参照ください。

CPU 使用率を下げる

高 CPU の原因となっているクエリを特定したら、次の方法を使用して CPU 使用率をさらに下げることができます。

  1. 調整の機会がある場合は、EXPLAINEXPLAIN ANALYZE を使用して注意事項を特定します。詳細については、EXPLAIN に関する PostgreSQL のドキュメントをご参照ください。
  2. 繰り返し実行されているクエリがある場合は、準備済みステートメントを使用して CPU への負担を軽減します。