找出真正佔用連線的程式

即使網站頁面看來簡單,資料庫連線仍可能耗盡。每個網頁程序、背景工作、排程任務及管理工具,都可能維持自己的連線池。發布新版時若新舊程序短暫並行,總需求可能突然增加。PostgreSQL 限制伺服器同時可用的連線數,也為特權存取預留部分名額,因此只看某個應用程式的連線池設定不足以算出整體預算。先列出所有會連向同一資料庫的元件,包括監測及維護工作,記錄其最多同時運行幾份、每份池大小,以及閒置時會否保留連線,再加總可能的同時需求。這是規劃上限,不代表所有連線任何時間都在工作。它能指出流量高峰或發布期間何處可能拒絕顧客請求,也讓團隊具體討論:應減少閒置連線、限制工作程序,還是加入連線池代理?

按條件理解伺服器上限

PostgreSQL 文件指出,max_connections 是同時連線的上限,常見預設值是 100,但初始化環境不同,實際值可以較低。修改這項設定需要重新啟動伺服器;調高上限亦會增加包括共享記憶體在內的資源分配。不要把常見預設值當成每個系統的安全目標。應讀取正在運行的資料庫設定與預留名額,再為維護及查錯留下空間。PostgreSQL 區分只供超級使用者的預留連線,以及供具備相應權限角色使用的預留連線;兩者有各自條件,安裝環境亦可能不同。一般網站不能假設自己可用緊急名額。託管資料庫服務商可能再加限制或連線池機制,應核對實際服務條款,不能照搬別家公司的示例。容量亦受記憶體、查詢需時及交易持續時間影響。單純增加連線,可能暫時掩蓋慢查詢,之後反而加重競爭,因此調高上限要有證據及負載測試。

建立可核對的容量算式

假設一個純示例系統有四個網頁實例,每個最多十條連線;兩個背景工作實例,每個最多八條;另有報表工作最多四條。配置上限是四乘十、加二乘八、再加四,即 60 條應用程式連線,尚未計管理存取及發布期間重疊。若滾動發布時短暫多開兩個網頁實例,規劃上限便成為 80。這些數字只供示範,實際工作表必須填入自己的自動擴展上限、程序數目與池設定。工作表同時列出平日及發布情境,不應只用平均觀察值。也要分清「已開啟連線」與「正在執行查詢」。若伺服器用量低但應用程式等候隊列增加,瓶頸可能在本地連線池、鎖或慢查詢,而非 PostgreSQL 的全域限制。反過來說,平均用量低亦不能證明短暫高峰從未碰到上限;比較數據時須記錄量度間隔與事件時間。

判斷連線池代理是否合適

PgBouncer 可接收用戶端連線,再管理較少的伺服器連線,但不同模式不能互換。其文件指出,session 模式在用戶端斷線後才釋放伺服器連線;transaction 模式在交易結束後釋放;statement 模式在每項查詢後釋放,且不容許跨多項語句的交易。交易模式可能適合簡短而獨立的工作,但依賴工作階段狀態的應用功能必須仔細測試兼容性。安裝代理本身不能保證解決擠塞。若請求在等待外部服務期間仍保持交易開啟,伺服器連線照樣被佔用;若每項查詢都慢,縮小池反而令等候增加。改模式前,要查清框架如何使用預備語句、暫存物件及連線本地設定,再以真實付款、管理及背景工作流程測試,包括查詢失敗與重新連線。PgBouncer 有按使用者及資料庫的設定,不能把單一預設池大小誤認為整個系統的唯一上限。

量度請求在哪裏等候

PostgreSQL 文件說明,pg_stat_activity 對每個伺服器程序提供一行資料,並列出當前活動,可協助區分正在工作、閒置以及長時間未結束交易的連線;可見資料仍受觀察帳戶權限影響。應在平常流量、計劃發布及受控負載測試期間記錄相關數量,並與應用程式連線池數據並排看:正在使用、可用、等候中的連線數及取得連線所需時間。若使用 PgBouncer,也應記錄用戶端及伺服器連線、等候用戶端。實際指標名稱因程式庫而異,所以要註明每個數值的意思。顧客請求變慢時,附時間戳的追蹤應能分辨它在等本地池、代理伺服器名額、資料庫鎖,還是在執行查詢。診斷資料不應記下顧客機密。沒有這種區分,團隊可能誤調高 max_connections,而真正問題是長交易,或個別程序的池太小。

以受控演練驗證上限

正式更改前,應以業務合理預期的流量與發布重疊情境演練。量度請求能否在自己訂明的可接受時間內完成、高峰過後隊列會否消退,以及管理員是否仍可連線查錯。刻意加入背景工作突增與一個網頁實例重啟,因為重新連線潮可能暴露平穩流量下看不到的限制。記錄受測設定、軟件版本、連線高峰、等候時間及失敗訊息。若測試失敗,每次只改一個可疑原因:縮短交易、減少過大的池、限制背景並行、調整代理設定,或根據證據修改伺服器容量。若更改令等候惡化,或破壞依賴工作階段的功能,便回退。小企業可以先用試算表與可重複的測試建立證據,毋須一開始便購買大型監測平台。最後得到的是配合自身工作負載的容量決定,而不是照抄通用連線數字。

按證據選擇下一項改動

工作表及演練之後,應選出一項具體行動,而非自動購買新服務或調大數字上限。若多個網頁實例保留大量閒置連線,可降低最少保留數或調整程式啟動連線池的方法,再觀察請求等候是否仍可接受。若背景批次同時開太多連線,可限制並行數,並核對批次能否在業務期限內完成。若少數長交易佔用主要容量,應先檢查那些流程,再考慮全域上限。若適合加入連線池代理,先用依賴工作階段功能的流程作兼容測試,再分別設定用戶端與伺服器上限,並在發布重疊時觀察隊列。把取捨寫清楚:較少伺服器連線可能保護 PostgreSQL,卻令用戶端等候;較大的池可能縮短本地等候,卻耗盡伺服器名額。業務負責人需要知道對付款或員工工作的預期影響、測試結果,以及何時回退。連線數只是保護工作完成的手段,不能單獨當成成功指標。

保留簡明的日常運作紀錄

連線容量不是只做一次的估算。新增背景工作、多開一個應用實例,或框架改變連線池預設值,都可能在資料庫沒有升級的情況下令舊預算失效。把工作表放進發布紀錄,要求每個新元件申報最多實例數及池設定。真正發生事故時,把時間、受影響的顧客操作、應用程式等候、PostgreSQL 活動,以及代理隊列記在同一筆紀錄,比只留下一張「用戶端過多」錯誤截圖更有助作決定。工作量改變、遷移服務商或更新管理連線的框架後,都應重看方案。若監測數據暫時不可用,就如實標示無法觀察,並在可行時安排受控測試;不要虛構高峰,也不要把資料缺失當成需求為零。驗收重點是系統能完成預定業務操作,同時在需求上升時保留查錯途徑。紀錄應簡短到下一位值班人員願意真正使用。

進行前先確認

  • 工作表涵蓋所有應用、背景工作及發布重疊。
  • 已讀取實際 PostgreSQL 與代理設定並測試兼容性。
  • 負載演練記下連線高峰、等候與恢復情況。

資料來源及延伸閱讀