就像所有複雜系統一樣,PostgreSQL 有時候也會出現狀況:查詢執行太久、伺服器負載變高、用戶開始緊張。日誌記錄就是讓我們能觀察資料庫內部運作的方式,目的是:
- 找出慢查詢 — 那些會拖慢應用程式的查詢。
- 優化效能 — 透過分析查詢行為來調整。
- 診斷錯誤 — 像是 constraint 違反或語法錯誤。
- 確保稽核 — 追蹤誰在伺服器上做了什麼操作。
日誌記錄的關鍵參數
PostgreSQL 的設定檔(postgresql.conf)裡有一堆跟日誌有關的參數。來看看最重要的幾個。
log_statement— SQL 查詢日誌記錄
log_statement 這個參數決定哪些 SQL 查詢會被寫進日誌。它可以設成以下幾種:
none— 不記錄查詢。ddl— 只記錄資料定義指令(像CREATE、ALTER、DROP)。mod— 記錄所有會改變資料的指令(像INSERT、UPDATE、DELETE)。all— 記錄所有 SQL 查詢(包含簡單的SELECT)。
範例:
如果你想記錄所有查詢,在 postgresql.conf 裡設:
log_statement = 'all'
如果你只想記錄資料變更指令:
log_statement = 'mod'
改完設定記得重啟伺服器:
sudo systemctl restart postgresql
log_duration— 執行時間日誌記錄
log_duration 這個參數可以把每個查詢的執行時間寫進日誌。這對找出哪些查詢最花時間很有用。
範例:
要開啟查詢執行時間記錄,設:
log_duration = on
如果你只想記錄慢查詢,可以用 log_min_duration_statement(我們等等會講)。
log_min_duration_statement— 慢查詢日誌記錄
這個參數只會把執行超過指定時間(毫秒)的查詢寫進日誌。超方便找出資料庫裡的「慢郎中」。
範例:
要記錄執行超過 1 秒的查詢:
log_min_duration_statement = 1000
如果你想不管多快多慢都記錄,設成 0:
log_min_duration_statement = 0
設成 -1 就是關掉這個功能。
log_line_prefix— 日誌訊息格式
log_line_prefix 這個參數可以自訂每條日誌訊息的格式。這樣你可以加上更多 context(像用戶名、PID、時間)。
範例:
要記錄用戶名、資料庫、時間和 process,可以設:
log_line_prefix = '%t [%p]: [%d]: [%u]: '
這裡:
%t— 查詢時間。%p— process 的 PID。%d— 資料庫名稱。%u— 用戶名稱。
所有可用選項清單:PostgreSQL 文件。
logging_collector— 日誌收集器
logging_collector 這個參數會把日誌寫進檔案。如果沒開,日誌只會送到標準輸出(stdout),這通常不太方便。
要啟用日誌收集器:
logging_collector = on
記得用 log_directory 和 log_filename 指定日誌檔案路徑:
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d.log'
參數實戰用法
來看看在實際情境下怎麼用這些日誌參數。
情境 1:記錄所有查詢
如果你剛開始用新資料庫,想看所有發生的事,設定:
log_statement = 'all'
log_line_prefix = '%t [%p]: [%d]: [%u]: '
這樣每個查詢都會被寫進日誌檔,debug 超方便!
情境 2:找慢查詢
如果你發現伺服器偶爾「卡卡的」,想找出問題查詢,設定:
log_min_duration_statement = 500 # 記錄超過 500 毫秒的查詢
log_line_prefix = '%t [%p]: [%d]: [%u]: [%r] '
這裡 %r 會加上 client 的 IP。這樣你很快就能找出拖慢伺服器的查詢。
情境 3:最小日誌模式
如果你的伺服器很穩,只想要最基本的 audit 日誌:
log_statement = 'mod'
log_duration = off
這樣只會記錄資料變更(像 INSERT、UPDATE)。
日誌分析
日誌開始累積資料後,會分析才有用!你可以:
用文字編輯器打開日誌檔:
cat /var/log/postgresql/postgresql.log
用分析工具(像 grep)找慢查詢:
grep "duration: " /var/log/postgresql/postgresql.log
用進階日誌分析工具,例如 pgBadger。
實用小技巧
日誌記錄太詳細會讓硬碟負載變高。正式環境只開你真的需要的參數就好。
定期清理或歸檔舊日誌檔,避免硬碟爆掉。
日誌記錄要有效率,就只收集你需要的資料。例如 log_min_duration_statement 可以讓你精準又省資源。
怎樣?現在我們設定 PostgreSQL 日誌、用它來分析查詢和提升效能都不是問題啦。正如某個(其實不只一個)不知名但很懂的工程師說過:「日誌讓我們能回頭看查詢的過去,也能修正資料庫的未來。」
GO TO FULL VERSION