web-dev-qa-db-ja.com

Postgresqlでリソースを大量に消費するSQL操作を見つける方法は? CPU使用率が急上昇

本番DBサーバーから頻繁にCPU使用率が高いというアラートを受け取っています。自分でこれについて詳しく調査したいので、CPU使用率が高い期間に実行中のDBクエリを収集しました。

SELECT * FROM pg_stat_activity;

収集されたデータから、UPDATE操作で頻繁にアクセスされるテーブルが1つあることがわかりました。さらなる調査の結果、テーブルがDBで最も頻繁にアクセスされるテーブルであり、リソースを大量に消費する可能性がないことがわかりました。

以下は、そのクエリについてEXPLAINから取得した詳細です。

                                  QUERY PLAN                                   
-------------------------------------------------------------------------------
 Update on foo_table  (cost=0.00..1271.14 rows=1 width=55)
   ->  Seq Scan on foo_table  (cost=0.00..1271.14 rows=1 width=55)
         Filter: (id = 2::bigint)
(3 rows)

これまでのところ、私が持っている唯一の特定のデータは、この高いCPU使用率のトリガー操作が発生している期間です。処理に時間がかかりすぎるクエリを特定することはできませんが。

以下のクエリを試してみましたが、説得力のある統計情報が見つかりませんでした。

SELECT relname, idx_tup_fetch + seq_tup_read as TotalReads from pg_stat_all_tables WHERE idx_tup_fetch + seq_tup_read != 0 order by TotalReads;

SELECT * FROM pg_stat_all_tables ORDER BY seq_scan DESC;

何が起こっているのかを理解する方法がないので、私は無力です。たとえば、ワークロードや、索引付けに関連する問題やクエリの最適化がそれを解決するので、それは正常です。

DB仕様:サイズ:150 GB以上のCPU:8コアRAM:16 GBストレージ:スワップなしのSSD。

1
JineshJK

問題は、いくつかのテーブルのインデックス作成にありました。次のクエリを実行することで、読み取り統計でこれらのテーブルを特定できました。

SELECT relname, idx_tup_fetch + seq_tup_read as TotalReads from pg_stat_all_tables WHERE idx_tup_fetch + seq_tup_read != 0 order by TotalReads desc LIMIT 10;
2
JineshJK

pg_stat_statements を見ることができます。 shared_preload_librariesで有効にする必要がありますが、どのステートメントが最も多くのリソースを消費するかについての優れたビューを提供します。 CPU時間を直接追跡することはありませんが、追跡された合計時間とI/O時間を見ると、通常は適切な見積もりを取得できます。

0
creinig

まず、9.2以降、パフォーマンスが大幅に改善されました。それ以来、監視ツールも大幅に改善されました。サポートされていないシステムのパフォーマンスの問題を調査するよりも、アップグレードに時間をかける方がおそらく意味があります。

次に、実際に問題がありますか?購入したCPUを使用してデータベースを使用することは、本質的に問題ではありません。一部の(名前のない)監視ツールがアラートを送信することも、問題があることを意味するのではなく、監視ツールが壊れているか、構成が不適切である可能性があります。 CPU使用率はどのくらいですか?最も使用頻度の高いプロセスのタイトルは何ですか?ユーザーはパフォーマンスについて不満を持っていますか?

キャプチャした特定のクエリについて、 "foo_table"にインデックスがあり、インデックスの先頭列として "id"がありますか?誰かが「id」という名前を付けることを決めた列は、おそらくインデックス化されるべきです。

Pg_stat_activityの手動検査で全体像が明らかになったかどうかわからない場合は、「auto_explain.log_min_duration」で auto_explain 拡張を使用して、遅い特定の実行をキャプチャできます。これはpg_stat_statementの優れた補完であり、特定のクエリの実行ではなく、一般的に各クエリの詳細を示します。

0
jjanes