連線與 backend 行程#

postmaster 行程的另一項任務是監聽傳入的連線。一旦有新客戶端出現,postmaster 就衍生一個獨立的 backend 行程。客戶端建立連線後,與這個 backend 開始一段 session;session 持續到客戶端斷線或連線中斷為止。

每客戶端一行程的代價#

伺服器必須為每個客戶端衍生一個獨立的 backend。當大量客戶端嘗試連線時,這會變成問題:

  • 記憶體:每個行程都需要 RAM 來快取目錄表格、預備語句、中間查詢結果等資料。開啟的連線越多,需要的記憶體越多。
  • 短連線的建立成本:若連線既短又頻繁(客戶端執行一個小查詢就斷線),建立連線、衍生新行程、做無謂的本地快取,這些成本高得不合理。
  • 行程清單掃描:啟動的行程越多,掃描其清單所需的時間越長,而這項操作執行得非常頻繁。結果是效能可能隨客戶端數量增加而下降

這個問題可透過連線池(connection pooling)解決,藉此限制被衍生的 backend 數量。

PostgreSQL 沒有內建這項功能,必須仰賴第三方方案:整合在應用程式伺服器中的 pooling 管理器,或外部工具如 PgBouncer、Odyssey。

連線池通常意味著每個伺服器 backend 會輪流執行不同客戶端的交易。這對應用程式開發施加了一些限制:只允許使用交易層級的本地資源,而非整個 session 的資源。

主從協定#

客戶端與伺服器必須使用相同的介接協定才能彼此理解。該協定通常以標準的 libpq 函式庫為基礎,但也存在其他自訂實作。

概括來說,協定讓客戶端能連上伺服器並執行 SQL 查詢。

連線總是以特定角色(使用者)的身分、建立到特定資料庫。儘管伺服器支援資料庫叢集,你仍必須為應用程式中要使用的每個資料庫分別建立連線。

連線時會進行認證:backend 行程驗證使用者身分(例如要求密碼),並檢查該使用者是否有權連上伺服器與指定的資料庫。

SQL 查詢以文字字串的形式傳給 backend 行程,該行程負責剖析文字、最佳化查詢、執行,並將結果回傳給客戶端