pg_stat_activity 基本上就是一個即時的視窗,讓你可以馬上看到資料庫現在到底在幹嘛。上一堂課我們講過基本概念,現在來深入玩玩這個超強工具。
最基本的 pg_stat_activity 查詢範例:
SELECT *
FROM pg_stat_activity;
這個查詢會列出所有活躍的連線還有目前執行的 query。很酷對吧!但資料會爆多,你可能會看到眼花,所以我們通常會過濾出最重要的資訊。
pg_stat_activity 的主要欄位
來看看幾個你一定會用到的重點欄位。query_start 會顯示 query 開始執行的時間,這對找出跑很久的操作超重要。pid 是連線的 process ID——這個用來管理(像是終止)連線。state_change 則是這個連線目前狀態被設定的時間,特別適合分析那些卡很久的問題狀態。
查詢活躍 process 的範例:
SELECT pid, usename, state, query, query_start
FROM pg_stat_activity
WHERE state = 'active';
怎麼追蹤跑很久的 query?
想像你是資料庫管理員,突然伺服器負載飆高。怎麼辦?先搞清楚是哪個 query 把資源吃光光。用 pg_stat_activity 來找出這些「貪吃」的 query 吧。
SELECT pid, usename, query, state, now() - query_start AS duration
FROM pg_stat_activity
WHERE state = 'active'
AND (now() - query_start) > interval '10 seconds';
這個查詢會列出所有執行超過 10 秒的 query。你可以根據需求調整這個時間。
終止有問題的 query
來看看怎麼砍掉那些跑太久、讓資料庫卡住的 query。用 pg_terminate_backend() 這個 function 就能強制終止 process。
終止特定 PID process 的範例:
SELECT pg_terminate_backend(12345);
這裡的 12345 就是 pg_stat_activity 裡的 process ID(pid 欄位)。
注意:終止 process 可能會讓沒正確結束的交易 rollback,所以要小心用。
如果你想自動砍掉所有「卡住」的 process,比如 idle 的交易,可以用下面這個 PL/pgSQL block。你已經學過程式設計了,loop(迴圈)這種東西應該很熟悉吧——就是重複執行某些指令直到條件不成立或資料處理完:
DO $$
DECLARE
r RECORD;
BEGIN
FOR r IN
SELECT pid
FROM pg_stat_activity
WHERE state = 'idle in transaction'
AND (now() - state_change) > interval '5 minutes'
LOOP
PERFORM pg_terminate_backend(r.pid);
END LOOP;
END $$;
這個動態解法可以幫你自動清掉有問題的交易。FOR 迴圈會跑過查詢結果的每一筆,然後對每個找到的 PID 執行終止。
很快我們就要開始學 PL/pgSQL 了,再忍一下啦 :P
依交易狀態過濾
有時你不只想找活躍的 query,還想知道有哪些連線處於特殊狀態,比如 idle 或 idle in transaction。這可以幫你在問題變嚴重前先發現潛在危機。
查找處於 idle in transaction 狀態交易的範例:
SELECT pid, usename, query, state, state_change
FROM pg_stat_activity
WHERE state = 'idle in transaction';
state_change 欄位會顯示這個狀態是什麼時候設定的。這樣你就能找出那些什麼事都沒做、但卻可能鎖住資料庫資源的長壽交易。
實戰應用
生產環境監控長 query:你可以設定定期監控那些超過某個時間門檻的 query,然後用 Slack、Telegram 或其他通知工具提醒你。這樣就能即時處理效能問題。
事故時分析 query:如果伺服器開始變慢,第一步就是看 pg_stat_activity,找出原因。這應該是你處理效能問題的標準流程。
資料庫維護:定期分析 pg_stat_activity 可以幫你追蹤沒效率的 query,然後優化它們(像是加 index 或重寫 query)。
監控時常見的錯誤有可能是過濾或解讀資料不對。比如你只過濾 active 狀態,可能會漏掉 idle in transaction 的 query,但這些也可能造成資源鎖死。另一個錯誤是太激進地終止 process,這可能導致交易被 rollback、資料遺失。下重手前一定要先看清楚狀況。
進階監控技巧
想更進階一點,可以寫複雜一點的查詢,像是依使用者、資料庫或 query 類型統計。比如你可以追蹤每個使用者平均花多少時間跑 query,或找出哪些資料庫有最多活躍連線。
另外也很推薦設定自動把長 query 記錄到 PostgreSQL log 檔,方法是調整 log_min_duration_statement 和 log_statement 這些設定。這樣你就能事後分析效能問題,還能找出應用程式的行為模式。
GO TO FULL VERSION