postgresSQL Extended Query執行過程和sharding-proxy的處理

2023-04-10 18:01:25

pg Extended Query

PostgreSQL: Documentation: 15: 55.2. Message Flow

多個階段,可複用

  1. Parse → DESCRIBE statement → SYNC

    1. Parse 解析, 將 sql 文字字串,解析成 named preparedStatement 語句(生命週期隨session) 預留位置和引數型別
    2. Describe 獲取後設資料,返回 pst 引數描述符 parameterDescription 和 結果集的行描述符 RowDescription
      由於此時 還沒執行 Bind,還未將語句傳輸到backend 執行,RowDescription中列的傳輸格式 codec format 還是0 ; 引數的型別應該也只是根據使用者端傳到 frontend 指定的型別來的?
    3. Sync 發完一串 extended messages 後需要發一個 sync 表示結束, 伺服器端一起處理;
      針對 sync 訊息,伺服器端返回是否在事務中執行的狀態 ‘T’ 在事務內, ‘I’ 不在事務內
  2. BIND → DESCRIBE portal → EXECUTE → SYNC

bind step, which creates a portal given a prepared statement and values for any needed parameters; and an execute step that runs a portal's query

  • bind 繫結階段 建立好一個可執行的 portal, 包括引數後設資料、返回結果集的後設資料 (row 欄位的pg型別 typeOid, 型別長度、 傳輸方式 0-text, 1-binary 等) 引數值
  • DESCRIBE portal;此時是發到 backend 來獲取後設資料的,入參和查詢結果的後設資料 才是真實的
  • execute 階段 執行並獲取結果集, 使用者端可以根據上一步 describe portal 拿到的 rowDescription 中列的 format 來決定是用 0-text 還是 1-binary 要求伺服器端對引數和查詢結果集中的欄位值進行 format 後傳輸

同一個session裡邊,步驟一執行過後 如果是 named portal ,後續就可以直接執行步驟二

步驟一執行完後, frontend session 快取好命名 pst, 下次同一個session再執行就能直接 走步驟二就可以了

sharding-proxy 執行紀錄檔

步驟一

‘P’ Parse stmtcache_1 sql

‘D’ ‘S’ Describe preparedStatement

[DEBUG] 2023-04-07 17:16:53.166 [nioEventLoopGroup-3-3] o.a.s.db.protocol.codec.PacketCodec - Read from client a3f6d846 :
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 50 00 00 00 aa 73 74 6d 74 63 61 63 68 65 5f 31 |**P**....stmtcache_1|
|00000010| 00 53 45 4c 45 43 54 20 22 69 64 22 2c 22 73 74 |.SELECT "id","st|
|00000020| 75 64 65 6e 74 5f 6e 61 6d 65 22 20 46 52 4f 4d |udent_name" FROM|
|00000030| 20 22 74 5f 73 74 75 64 65 6e 74 5f 69 6e 66 6f | "t_student_info|
|00000040| 22 20 57 48 45 52 45 20 22 74 5f 73 74 75 64 65 |" WHERE "t_stude|
|00000050| 6e 74 5f 69 6e 66 6f 22 2e 22 69 64 22 20 3d 20 |nt_info"."id" = |
|00000060| 24 31 20 41 4e 44 20 22 74 5f 73 74 75 64 65 6e |$1 AND "t_studen|
|00000070| 74 5f 69 6e 66 6f 22 2e 22 69 64 22 20 3d 20 24 |t_info"."id" = $|
|00000080| 32 20 4f 52 44 45 52 20 42 59 20 22 74 5f 73 74 |2 ORDER BY "t_st|
|00000090| 75 64 65 6e 74 5f 69 6e 66 6f 22 2e 22 69 64 22 |udent_info"."id"|
|000000a0| 20 4c 49 4d 49 54 20 31 00 00 00 44 00 00 00 11 | LIMIT 1...**D**....|
|000000b0| 53 73 74 6d 74 63 61 63 68 65 5f 31 00 53 00 00 |**S**stmtcache_1.**S**..|
|000000c0| 00 04                                           |..              |
+--------+-------------------------------------------------+----------------+

請求報文 解析成對應的 packet 物件 xxPacket,並建立對應的執行器 xxExecutor

執行結果

此時 rowDescription, dataFormat都是0

步驟二

‘B’ Bind

‘D’ + ‘P’ Describe porta

‘E’ Execute

‘S’ Sync

[DEBUG] 2023-04-07 17:16:53.304 [nioEventLoopGroup-3-3] o.a.s.db.protocol.codec.PacketCodec - Read from client a3f6d846 :
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 42 00 00 00 37 00 73 74 6d 74 63 61 63 68 65 5f |**B**...7.stmtcache_|
|00000010| 31 00 00 02 00 01 00 01 00 02 00 00 00 08 00 00 |1...............|
|00000020| 00 00 00 00 00 16 00 00 00 08 00 00 00 00 00 00 |................|
|00000030| 00 16 00 02 00 01 00 00 44 00 00 00 06 50 00 45 |........**D**....P.**E**|
|00000040| 00 00 00 09 00 00 00 00 00 53 00 00 00 04       |.........**S**....  |

報文解析,和對應執行器構建

響應報文

RowDescription 響應結果集的行描述符,DataRowPacket 響應行資料

列 id ,值是 binary 格式 對應 columnDescription 的 dataFormat = 1 (binary)