CodeGym /課程 /SQL SELF /查詢執行日誌記錄

查詢執行日誌記錄

SQL SELF
等級 45 , 課堂 3
開放

就像所有複雜系統一樣,PostgreSQL 有時候也會出現狀況:查詢執行太久、伺服器負載變高、用戶開始緊張。日誌記錄就是讓我們能觀察資料庫內部運作的方式,目的是:

  1. 找出慢查詢 — 那些會拖慢應用程式的查詢。
  2. 優化效能 — 透過分析查詢行為來調整。
  3. 診斷錯誤 — 像是 constraint 違反或語法錯誤。
  4. 確保稽核 — 追蹤誰在伺服器上做了什麼操作。

日誌記錄的關鍵參數

PostgreSQL 的設定檔(postgresql.conf)裡有一堆跟日誌有關的參數。來看看最重要的幾個。

  1. log_statement — SQL 查詢日誌記錄

log_statement 這個參數決定哪些 SQL 查詢會被寫進日誌。它可以設成以下幾種:

  • none — 不記錄查詢。
  • ddl — 只記錄資料定義指令(像 CREATEALTERDROP)。
  • mod — 記錄所有會改變資料的指令(像 INSERTUPDATEDELETE)。
  • all — 記錄所有 SQL 查詢(包含簡單的 SELECT)。

範例:

如果你想記錄所有查詢,在 postgresql.conf 裡設:

log_statement = 'all'

如果你只想記錄資料變更指令:

log_statement = 'mod'

改完設定記得重啟伺服器:

sudo systemctl restart postgresql
  1. log_duration — 執行時間日誌記錄

log_duration 這個參數可以把每個查詢的執行時間寫進日誌。這對找出哪些查詢最花時間很有用。

範例:

要開啟查詢執行時間記錄,設:

log_duration = on

如果你只想記錄慢查詢,可以用 log_min_duration_statement(我們等等會講)。

  1. log_min_duration_statement — 慢查詢日誌記錄

這個參數只會把執行超過指定時間(毫秒)的查詢寫進日誌。超方便找出資料庫裡的「慢郎中」。

範例:

要記錄執行超過 1 秒的查詢:

log_min_duration_statement = 1000

如果你想不管多快多慢都記錄,設成 0

log_min_duration_statement = 0

設成 -1 就是關掉這個功能。

  1. log_line_prefix — 日誌訊息格式

log_line_prefix 這個參數可以自訂每條日誌訊息的格式。這樣你可以加上更多 context(像用戶名、PID、時間)。

範例:

要記錄用戶名、資料庫、時間和 process,可以設:

log_line_prefix = '%t [%p]: [%d]: [%u]: '

這裡:

  • %t — 查詢時間。
  • %p — process 的 PID。
  • %d — 資料庫名稱。
  • %u — 用戶名稱。

所有可用選項清單:PostgreSQL 文件

  1. logging_collector — 日誌收集器

logging_collector 這個參數會把日誌寫進檔案。如果沒開,日誌只會送到標準輸出(stdout),這通常不太方便。

要啟用日誌收集器:

logging_collector = on

記得用 log_directorylog_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

這樣只會記錄資料變更(像 INSERTUPDATE)。

日誌分析

日誌開始累積資料後,會分析才有用!你可以:

用文字編輯器打開日誌檔:

cat /var/log/postgresql/postgresql.log

用分析工具(像 grep)找慢查詢:

grep "duration: " /var/log/postgresql/postgresql.log

用進階日誌分析工具,例如 pgBadger

實用小技巧

日誌記錄太詳細會讓硬碟負載變高。正式環境只開你真的需要的參數就好。

定期清理或歸檔舊日誌檔,避免硬碟爆掉。

日誌記錄要有效率,就只收集你需要的資料。例如 log_min_duration_statement 可以讓你精準又省資源。

怎樣?現在我們設定 PostgreSQL 日誌、用它來分析查詢和提升效能都不是問題啦。正如某個(其實不只一個)不知名但很懂的工程師說過:「日誌讓我們能回頭看查詢的過去,也能修正資料庫的未來。」

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION