W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
協(xié)議在啟動(dòng)和正常操作過(guò)程中有不同的階段。在啟動(dòng)階段里,前端打開(kāi)一個(gè)到服務(wù)器的連接并且認(rèn)證自身以滿(mǎn)足服務(wù)器(這可能涉及到一條或多條消息,取決于使用的認(rèn)證方法)。 如果一切正常,服務(wù)器就發(fā)送狀態(tài)信息給前端,并最后進(jìn)入正常操作。除了最初的啟動(dòng)請(qǐng)求消息之外,協(xié)議的這個(gè)部分是服務(wù)器驅(qū)動(dòng)的。
在正常操作中,前端發(fā)送查詢(xún)和其它命令到后端,然后后端返回查詢(xún)結(jié)果和其它響應(yīng)。在少數(shù)幾種情況(比如NOTIFY
)中,后端會(huì)發(fā)送未被請(qǐng)求的消息,但這個(gè)會(huì)話(huà)中的絕大多部分都是由前端請(qǐng)求驅(qū)動(dòng)的。
會(huì)話(huà)的終止通常是由前端來(lái)選擇的,但是也可以在某些情況下由后端強(qiáng)制執(zhí)行。不管在那種情況下,如果后端關(guān)閉連接,那么它將在退出之前回滾所有打開(kāi)的(未完成的)事務(wù)。
在正常操作中,SQL命令可以通過(guò)兩個(gè)子協(xié)議中的任何一個(gè)執(zhí)行。 在“簡(jiǎn)單查詢(xún)”協(xié)議中,前端只是發(fā)送一個(gè)文本查詢(xún)串, 然后后端馬上分析并執(zhí)行它。在“擴(kuò)展查詢(xún)”協(xié)議中, 查詢(xún)的處理被分割為多個(gè)步驟:分析、參數(shù)值綁定和執(zhí)行。這樣就可以提供靈活性和性能的改進(jìn),但代價(jià)是額外的復(fù)雜性。
正常操作還有用于類(lèi)似COPY
這樣的額外的子協(xié)議。
所有通訊都是通過(guò)一個(gè)消息流進(jìn)行的。消息的第一個(gè)字節(jié)標(biāo)識(shí)消息類(lèi)型, 然后后面跟著的四個(gè)字節(jié)聲明消息剩下部分的長(zhǎng)度(這個(gè)長(zhǎng)度包括長(zhǎng)度域自身,但是不包括消息類(lèi)型字節(jié))。 剩下的消息內(nèi)容由消息類(lèi)型決定。由于歷史原因,客戶(hù)端發(fā)送的最初的消息(啟動(dòng)消息)不包含消息類(lèi)型字節(jié)。
為了避免失去與消息流的同步,服務(wù)器和客戶(hù)端通常都是把整個(gè)消息讀取到一個(gè)緩沖區(qū)里(使用字節(jié)計(jì)數(shù)), 然后才試圖處理其內(nèi)容。這樣在處理內(nèi)容的過(guò)程時(shí)如果發(fā)現(xiàn)錯(cuò)誤,就比較容易恢復(fù)。 在非常極端的情況下(比如說(shuō)沒(méi)有足夠的內(nèi)存緩沖消息),接收端可以使用字節(jié)計(jì)數(shù)來(lái)判斷它在繼續(xù)讀取消息之前需要跳過(guò)多少輸入。
反之,服務(wù)器和客戶(hù)端都需要注意決不能發(fā)送一條不完整的消息。保證這一點(diǎn)的方法通常是在發(fā)送整條信息之前先在一個(gè)緩沖區(qū)里整理整條消息。 如果在發(fā)送或者接受一條消息的中間發(fā)生了通訊錯(cuò)誤,那么唯一合理的響應(yīng)是放棄連接,因?yàn)榛謴?fù)消息邊界同步的希望很小。
在擴(kuò)展查詢(xún)協(xié)議中,SQL命令的執(zhí)行是分割成多個(gè)步驟的。步驟與步驟之間保存的狀態(tài)是由兩類(lèi)的對(duì)象代表的:預(yù)備語(yǔ)句(prepared statements)和入口(portals)。 一個(gè)預(yù)備語(yǔ)句代表一個(gè)文本查詢(xún)字符串的經(jīng)過(guò)分析、語(yǔ)意解析以及規(guī)劃之后的結(jié)果。一個(gè)預(yù)備語(yǔ)句不代表它已經(jīng)可以被執(zhí)行,因?yàn)樗赡苓€缺乏 參數(shù)的值。 一個(gè)入口代表一個(gè)已經(jīng)可以執(zhí)行的或者已經(jīng)被部分執(zhí)行過(guò)的語(yǔ)句,所有缺失的參數(shù)值都已經(jīng)填充到位了(對(duì)于
SELECT
語(yǔ)句,入口等效于一個(gè)打開(kāi)的游標(biāo), 但我們使用不同的術(shù)語(yǔ)是因?yàn)橛螛?biāo)不能處理非SELECT
語(yǔ)句)。
完整的執(zhí)行周期包括一個(gè)分析步驟, 它從一個(gè)文本的查詢(xún)字符串里創(chuàng)建一個(gè)預(yù)備語(yǔ)句; 一個(gè)綁定步驟, 它用一個(gè)預(yù)備語(yǔ)句和任何所需的參數(shù)值創(chuàng)建一個(gè)入口;以及一個(gè)執(zhí)行步驟,它運(yùn)行一個(gè)入口中的查詢(xún)。如果查詢(xún)會(huì)返回?cái)?shù)據(jù)行(SELECT
、SHOW
等),
執(zhí)行步驟會(huì)被告知只抓取有限的一些行,這樣就可能需要多個(gè)執(zhí)行步驟來(lái)完成操作。
后端可以跟蹤多個(gè)預(yù)備語(yǔ)句和入口(但是要注意,這些只存在于一個(gè)會(huì)話(huà)內(nèi)部,不能在會(huì)話(huà)之間共享)?,F(xiàn)有的預(yù)備語(yǔ)句和入口都是用創(chuàng)建它們的時(shí)候賦予的名字引用的。 另外,還存在一個(gè)“未命名”的預(yù)備語(yǔ)句和入口。 盡管它們的行為和命名對(duì)象大部分相同,但是它們是針對(duì)只執(zhí)行一次然后就拋棄的查詢(xún)而優(yōu)化的, 而在命名對(duì)象上的操作是針對(duì)多次使用而優(yōu)化的。
特定數(shù)據(jù)類(lèi)型的數(shù)據(jù)可以用幾種不同的格式中的任意一種來(lái)傳遞。 從PostgreSQL 7.4開(kāi)始,只支持“文本”和“二進(jìn)制”兩種格式, 但是協(xié)議為未來(lái)的擴(kuò)展提供了的手段。任意值要求的格式用一個(gè) 格式代碼聲明。 客戶(hù)端可以為每個(gè)傳輸?shù)膮?shù)值和查詢(xún)結(jié)果的每個(gè)列指定一個(gè)格式代碼。 文本的格式代碼是零,二進(jìn)制的格式代碼是一,所有其它的格式代碼都保留給將來(lái)定義。
文本形式的數(shù)值是特定數(shù)據(jù)類(lèi)型的輸入/輸出轉(zhuǎn)換函數(shù)生成或接受的任何字符串。在傳輸形式上,字符串沒(méi)有末尾空字符;如果前端要想把收到的值當(dāng)作C字符串處理,那么必須自己加上一個(gè)(順便說(shuō)一下,文本格式不允許嵌入空字符)。
整數(shù)的二進(jìn)制形式采用網(wǎng)絡(luò)字節(jié)序(高位在前)。對(duì)于其它數(shù)據(jù)類(lèi)型,請(qǐng)參考文檔或者源代碼獲取其二進(jìn)制形式的信息。請(qǐng)注意,復(fù)雜數(shù)據(jù)類(lèi)型的二進(jìn)制形式可能在不同服務(wù)器版本之間變化; 文本格式通常是最具有移植性的選擇。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: