協議有啟動和正常執行兩個獨立階段。在啟動階段,前端連線到伺服器並進行身份驗證,以使伺服器滿意。(這可能涉及單個訊息,或根據所使用的身份驗證方法而涉及多個訊息。)如果一切順利,伺服器將傳送狀態資訊給前端,最後進入正常執行。除了初始的啟動請求訊息外,協議的這部分由伺服器驅動。
在正常執行期間,前端向後端傳送查詢和其他命令,後端則傳送查詢結果和其他響應。有幾種情況(例如 NOTIFY
),後端會發送未請求的訊息,但絕大多數情況下,會話的這部分由前端請求驅動。
會話的終止通常由前端選擇,但在某些情況下可能由後端強制執行。無論哪種情況,當後端關閉連線時,它將在退出前回滾任何已開啟(未完成)的事務。
在正常執行中,可以透過以下兩種子協議之一來執行 SQL 命令。在“簡單查詢”協議中,前端只需傳送一個文字查詢字串,後端會立即對其進行解析和執行。在“擴充套件查詢”協議中,查詢的處理分為多個步驟:解析、引數值繫結和執行。這提供了靈活性和效能優勢,但代價是增加了複雜性。
正常執行有其他子協議用於特殊操作,例如 COPY
。
所有通訊都透過訊息流進行。訊息的第一個位元組標識訊息型別,接下來的四個位元組指定其餘訊息的長度(此長度計數包括其本身,但不包括訊息型別位元組)。訊息的其餘內容取決於訊息型別。出於歷史原因,客戶端傳送的第一個訊息(啟動訊息)沒有初始的訊息型別位元組。
為了避免與訊息流失去同步,伺服器和客戶端通常會在嘗試處理其內容之前,將整個訊息讀取到緩衝區中(使用位元組計數)。這使得在處理內容時檢測到錯誤時易於恢復。在極端情況下(例如記憶體不足以緩衝訊息),接收方可以使用位元組計數來確定在恢復讀取訊息之前要跳過多少輸入。
相反,伺服器和客戶端都必須小心,切勿傳送不完整訊息。這通常透過在開始傳送之前將整個訊息封存在緩衝區中來完成。如果在傳送或接收訊息的過程中發生通訊故障,唯一明智的響應是放棄連線,因為幾乎不可能恢復訊息邊界同步。
在擴充套件查詢協議中,SQL 命令的執行分為多個步驟。在步驟之間保留的狀態由兩種型別的物件表示:準備好的語句和門戶。準備好的語句表示對文字查詢字串進行解析和語義分析的結果。準備好的語句本身並不準備執行,因為它可能缺少引數的特定值。門戶表示一個已準備好執行或已部分執行的語句,任何缺失的引數值都已填補。(對於 SELECT
語句,門戶等同於一個開啟的遊標,但我們選擇使用不同的術語,因為遊標不處理非 SELECT
語句。)
整體執行週期包括一個解析步驟,該步驟從文字查詢字串建立準備好的語句;一個繫結步驟,該步驟根據準備好的語句和任何所需引數的值建立門戶;以及一個執行步驟,該步驟執行門戶的查詢。對於返回行的查詢(SELECT
、SHOW
等),可以指示執行步驟僅獲取有限數量的行,因此可能需要多個執行步驟來完成操作。
後端可以跟蹤多個準備好的語句和門戶(但請注意,這些僅存在於會話中,並且從不跨會話共享)。現有的準備好的語句和門戶透過建立時分配的名稱來引用。此外,還存在一個“未命名”的準備好的語句和門戶。儘管它們在很大程度上與命名物件行為相同,但對它們的と操作針對的是僅執行一次然後丟棄查詢的情況進行了最佳化,而對命名物件的操作則針對的是期望多次使用的情況進行了最佳化。
特定資料型別的資料可能以幾種不同的格式傳輸。截至 PostgreSQL 7.4,唯一支援的格式是“文字”和“二進位制”,但協議為將來的擴充套件提供了規定。任何值的所需格式由格式程式碼指定。客戶端可以為每個傳輸的引數值和每個查詢結果列指定一個格式程式碼。文字的格式程式碼為零,二進位制的格式程式碼為一,所有其他格式程式碼均保留供將來定義。
值的文字表示就是特定資料型別的輸入/輸出轉換函式生成的字串。在傳輸的表示中,沒有尾隨的 null 字元;如果前端想將接收到的值作為 C 字串處理,它必須為其新增一個。(順便說一句,文字格式不允許嵌入 null。)
整數的二進位制表示使用網路位元組序(最高有效位元組在前)。對於其他資料型別,請查閱文件或原始碼以瞭解二進位制表示。請記住,複雜資料型別的二進位制表示可能會在伺服器版本之間發生變化;文字格式通常是更具可移植性的選擇。
當前最新的協議版本是 3.2。但是,為了向後相容不支援版本協商的舊伺服器版本和中介軟體,libpq 預設仍使用協議版本 3.0。
單個伺服器可以支援多個協議版本。初始的啟動請求訊息告知伺服器客戶端嘗試使用的協議版本。如果客戶端請求的主版本不受伺服器支援,連線將被拒絕(例如,如果客戶端請求協議版本 4.0,而此版本在撰寫本文時不存在,則會發生這種情況)。如果客戶端請求的次版本不受伺服器支援(例如,客戶端請求版本 3.2,但伺服器僅支援 3.0),伺服器可以拒絕連線,或者以 NegotiateProtocolVersion 訊息響應,其中包含其支援的最高次協議版本。然後,客戶端可以選擇繼續使用指定的協議版本進行連線,或中止連線。
協議協商已在 PostgreSQL 版本 9.3.21 中引入。早期版本如果客戶端請求的次版本不受伺服器支援,則會拒絕連線。
表 54.1 顯示了當前支援的協議版本。
表 54.1. 協議版本
版本 | 由...支援 | 描述 |
---|---|---|
3.2 | PostgreSQL 18 及更高版本 | 當前最新版本。用於查詢取消的金鑰長度從 4 位元組增加到可變長度欄位。BackendKeyData 訊息已更改以適應這一點,CancelRequest 訊息已重新定義為具有可變長度的負載。 |
3.1 | - | 保留。版本 3.1 未被任何 PostgreSQL 版本使用,但它被跳過了,因為流行的 pgbouncer 應用程式的舊版本在協議協商中存在一個錯誤,導致它錯誤地聲稱支援版本 3.1。 |
3.0 | PostgreSQL 7.4 及更高版本 | |
2.0 | 最高達 PostgreSQL 13 | 有關詳細資訊,請參閱 PostgreSQL 文件的先前版本。 |
如果您在文件中看到任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。