Postgresql

如何在 Postgresql 中查找資源密集型 SQL 操作?高 CPU 使用率峰值

  • December 5, 2019

我經常收到來自生產數據庫伺服器的高 CPU 使用率警報。由於我想自己對此進行更多調查,因此我收集了該高 CPU 使用時間段的正在執行的數據庫查詢。

SELECT * FROM pg_stat_activity;

從收集到的數據中,觀察到有一張頻繁訪問的表進行了UPDATE操作。通過進一步調查,我了解到該表是數據庫中訪問頻率最高的表,並且沒有什麼可能佔用資源。

以下是我從 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;

我很無助,因為我無法弄清楚發生了什麼,比如這是正常的,因為工作負載還是索引相關問題或查詢優化會解決它等等。

數據庫規格:大小:150+ GB CPU:8 核 RAM:16 GB 儲存:無交換的 SSD。

問題在於幾個表的索引。通過執行以下查詢,我能夠辨識具有讀取統計資訊的那些表。

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;

首先,自 9.2 以來已經有了很多性能改進。從那時起,監控工具也有了很大的改進。花時間升級而不是調查不受支持的系統上的性能問題可能更有意義。

接下來,你真的有問題嗎?您的數據庫使用您為其購買的 CPU 本身並不是問題。某些(未命名的)監控工具向您發送警報也不意味著您有問題,您可能只是有一個損壞或配置不當的監控工具。CPU使用率有多高?它是否告訴您使用率最高的流程的流程標題是什麼?您的使用者是否在抱怨性能?

對於您擷取的特定查詢,“foo_table”上是否有一個索引,其中“id”作為索引中的前導列?有人決定命名為“id”的列很可能應該被索引。

如果您不確定您對 pg_stat_activity 的手動檢查是否揭示了整個情況,那麼您可以使用帶有“auto_explain.log_min_duration”的auto_explain擴展來擷取速度較慢的特定執行。這是對 pg_stat_statement 的一個很好的補充,它告訴你更多關於每個查詢的一般資訊,而不是它們的具體執行。

引用自:https://dba.stackexchange.com/questions/243599