PostgreSQL 的 Session 和 Connection 含義差在哪?哪個對維運更有幫助?
說明 PostgreSQL 中 connection 與 session 的差異,以及為何 active sessions 對判斷資料庫健康度更有用。
在維運客戶的 RDS 時,因為開啟了 Performance Insight,看到了 RDS Summary 介面上的 current activity 從 connections 統計變成 xxx sessions,所以想記錄一下這次學到的知識。
Connection
- 1 TCP connection = 1 PostgreSQL backend process
- Client 連到 PostgreSQL 後,PostgreSQL 會 fork 一個 OS process,且這個 process 大多時間在執行
poll()/epoll(),佔一點點記憶體,通常執行時不會跑在 CPU- 執行
poll()/epoll()的含義:我現在沒事做,我要等 client 的 socket 何時有資料進來(可讀),或何時可以寫出去(可寫)。
- 執行
- 因此,connection 數量只能拿來推估 backend process 數、memory pressure 等資源佔用單位,無法推測實際 DB 內在執行什麼作業
Session
- Session = 一個 connection 在資料庫端的 session context,包含它的狀態、目前在等什麼、上一個 query、transaction 狀態等等
- 這些行為與狀態,會被記錄在共享記憶體中,持續被 backend process 更新,而監控上也可以讀取這些資訊
Session 的狀態機
- active:backend 正在處理 client 請求(parse/plan/execute),或正在等某個資源完成(例如 IO/lock;有些情況下 state 仍可能是 active,但 wait_event 會紀錄在等什麼)
- idle:backend 沒有在執行 query,正在等 client 的下一個封包/命令。這時候 backend 多半在 OS 層面做的事就是:阻塞式等待 socket 可讀(像是 poll/epoll)
- idle in transaction:client 已經
BEGIN進 transaction,跑過至少一個 query,但現在停住,還沒COMMIT/ROLLBACK。backend 現在可能只是等 client 下一個命令,但因為 transaction 沒結束,會保留 transaction snapshot、可能持有鎖、阻擋 vacuum 等- 可以理解成:「人還在,而且手上拿著工具/占著機台,但在發呆」(所以危險)
- idle in transaction (aborted):transaction 裡出錯了(例如 SQL error),transaction 已經進入 aborted 狀態;接下來只有
ROLLBACK才能脫離
為什麼「session 對健康度判斷更有用」?
比較 Connection 和 Session 狀態之後,我們能比較明確的知道,connection 比較像是提供資源佔用單位的推測,也就是系統因為「存在這些連線」所需要消耗的資源成本;而 session 更像是推測系統此刻正在處理多少「同時進行的工作」、會不會排隊等工作單位的資訊。
而資料庫「變慢」的本質,不是因為連線數變多,而是因為同一時間需要前進的工作量,超過了可用資源。對 PostgreSQL 來說,真正會拉長查詢時間的原因只有幾類:CPU 同時被太多 backend 競爭、IO 佇列堆積、lock / latch 造成等待。這些問題的共同點是「有多少個 session 同時處於需要資源才能繼續的狀態」,而不是「有多少條連線存在」。
session(特別是 active session / AAS)之所以對健康度判斷更有用,是因為它直接量化了「工作單位 vs 可用資源」的關係。每一個 active session,代表一個 backend 正在執行 SQL,或正在等待 CPU、IO、lock 等關鍵資源;當 active session 的數量接近甚至超過 vCPU 時,代表工作開始排隊,OS 必須頻繁 context switch,query latency 會系統性上升。
因此,session 描述的是「壓力來源」,CPU/IO utilization 描述的是「結果」。也就是說,用 session 來判斷健康度,能在效能惡化之前就看見趨勢,這也是為什麼 AWS 會用 AAS 作為 Performance Insights 的核心指標。
為什麼「active sessions > vCPU」是健康分界線?
根據 PostgreSQL 的 CPU 使用模型,單一的 process 同一時間只能跑在一個 CPU core 上,沒有 intra-query parallelism(除非特別的 parallel query)。再根據前面討論的,1 active session ≈ 1 runnable process。因此,16 vCPU 的資料庫機型,同一時間最多可以順暢地跑 16 個 active session。
當 active session ≤ vCPU 時,OS scheduler 的行為如下:每個 backend 都有 core 可以跑、context switch 極少、query latency 穩定,因此效能是線性可預期的。
但當 active sessions > vCPU 時,OS scheduler 會產生以下的行為:backend process 開始搶 CPU、OS 開始頻繁 context switch、query 因為排隊變慢。這時會看到 CPU 100%、query latency 上升、throughput 不一定上升(甚至下降)。
由此可以再次證明,CPU utilization 是結果、而 active sessions 則是原因。要是能夠在 CPU 100% 前,就先透過 active session 數量判斷系統健康度,在維運上的對應修復也能夠更即時。
補充:對應到 MySQL 的名稱
| 概念 | PostgreSQL | MySQL |
|---|---|---|
| 連線數 | connections | Threads_connected |
| 工作單位 | active sessions / AAS | Threads_running |
| 等待原因 | wait_event | performance_schema wait |
| 健康判斷 | AAS vs vCPU (AAS, Average Active Sessions) | Threads_running vs vCPU |