客戶端發起查詢請求
客戶端與服務進程進行通信中有兩個關鍵的共享緩衝區:
- PgRecvBuffer:存儲服務端接收請求,默認8192字節
- PqSendBuffer:存儲服務端發送請求,默認8192字節
客戶端與服務進程之間存在兩種連接方式:網絡連接與本地訪問;根據這兩種不同的連接方式,PG可以獲取客戶端發送的請求,這時查詢的命令將會被保存到inBuf裏。
static int
ReadCommand(StringInfo inBuf)
{
int result;
if (whereToSendOutput == DestRemote)
result = SocketBackend(inBuf);
else
result = InteractiveBackend(inBuf);
return result;
}
PostgrsSQL本身是一種基於消息的協議用於服務進程與客戶端之間的通信,即通信的基本單元就是消息流。這裏主要將消息分爲六種:
- 啓動消息
- 簡單查詢
- 擴展查詢
- 函數調用
- 取消請求
- 終止
其中我們用的比較常見就是curd 簡單查詢,用字符’Q’表示,也就是函數ReadCommand的返回值,而inBuf則保存了查詢命令。在獲取了查詢請求後,通過exec_simple_query來進行查詢。
淺析查詢流程
詞法分析
編譯器必須檢查查詢字符串(以純文本形式到達)是否爲合法語法。如果語法正確將建立一個分析樹並返回之,否則將返回一個錯誤。 語法分析器和詞法分析器使用著名的Unix工具bison和flex實現。
詞法分析器定義在文件scan.l中,並負責識別標識符、SQL關鍵詞等。對於找到的每一個關鍵詞或標識符將生成一個記號並返回給語法分析器。
語法解析
遍歷詞法分析過程生成的分析樹,將他們轉化成同一的數據結構Query,如果是查詢命令則對查詢進行重寫。
優化器
對於輸入的Query生成多個查詢計劃plan,對於一個sql來說可以生成至少一個查詢計劃
執行器
按照查詢計劃生成最終的查詢結果。