-
Notifications
You must be signed in to change notification settings - Fork 9
Postgre Frontend Backend Protocol简介
flabby edited this page Jun 21, 2017
·
1 revision
- 基于消息的应用层协议
- 可以使用TCP socket或者unix domain socket
- 文档很完善,都有覆盖;
- Startup Pharse
- 环境变量交互:user、db、encoding、etc
- auth:passwd、SSL
- 由server驱动,除了最开始的startup消息;
- Normal Pharse
- 客户端query,服务端响应;
- 服务端也有一些主动发送的消息;
- 两种子协议:
- Simple Query: client发送查询文本,服务端立马执行,响应;
- Extended Query:分为多个步骤:
- Prepare、parse、bind、describe、execute、sync等;
- jdbc、pdo都是extended
- 其他特殊指令:COPY等
- Prepared statement
- results of parse、analysis and plan
- 缺少实参;
- Prepared statement 分为named,unamed;
- portal :
- 有实参;
[ header ] [ body ]
- 两种版本的header
- v3: [ message_type (1 byte) | length (4 bytes) ]
- v2: [ length (4 bytes) | message_type (4 bytes) ]
- length是网络字节序的int32;表示的是到消息剩余长度(包括自身4个字节);
-
建立连接后, client发送startup message;
- case PKT_STARTUP: 包括username, dbname; 服务端根据配置文件确认是否需要额外验证;
- case PKT_SSLREQ: SSL请求的包,服务端做出响应;
-
StartUp message:
- PKT_STARTUP_V2 0x20000
- PKT_STARTUP 0x30000
-
可能的响应包:
- ErrorResponse 'E'
- AuthenticationOk 'R' body = 0;
- AuthenticationMD5Password 'R' body = 4 bytes salt;
- AuthenticationCryptPassword 'R'
- ...
-
client收到AuthOk后,server发送一些ParameterStatus、BackendKeyData,最终发送ReadyForQuery
-
ParameterStatus message: 'S'
- 包括encoding、datestyle、等
- jdbc需要响应对应的client_encoding、session_authorization
-
BackendKeyData: 'K'
- client用来cancel的cancel key;
- 不需要响应这个消息;
-
ReadyForQuery: 'Z' body = 'I';
- start up结束,client可以请求;
-
ErrorResponse 'E' body = "SERROR", "C42601", 'M', msg, ""
-
NoticeResponse 'N' body = "SNOTICE", "C00000", 'M', msg, ""
- SimpleQuery 'Q'
- one packet
- 可能的响应:
- CommandComplete 'C'
- ErrorResponse 'E'
- CopyInResponse 'G'
- etc
- 分为多个阶段 (parsed statement可以多次使用提高效率)
- parse
- bind
- execute
- sync
- 包括sql或者变量占位符,name;
- 分为named unamed;
- named 可以一直存在,直到显示deallocate
- unamed一直存在到下一次的parse
- 响应 ParseComplete '1'
- Bind message 'B'
- 可以包括parsed statement name,portal name;
- 响应 BindComplete '2'
- bind成功,会生一个portal对象;
- 响应
- NoData 'n'
- RowDescription 'T'
- 包括portal name,最大result-row count
- 响应 CommandComplete
- 结束当前transcation,返回结果;
- Close
- Flush
通过抓包分析一个jdbc,通过user1连接数据库test,执行一个insert语句的过程;
- s1. client 发送Startup message
- header: length = 0x67, type=0x030000;
- body: user user1 database test client_encoding UTF8 DateStyle ISO ...
0040 00 00 00 67 00 03 00 00 75 73 65 72 00 75 .....g....user.u
0050 73 65 72 31 00 64 61 74 61 62 61 73 65 00 74 65 ser1.database.te
0060 73 74 00 63 6c 69 65 6e 74 5f 65 6e 63 6f 64 69 st.client_encodi
0070 6e 67 00 55 54 46 38 00 44 61 74 65 53 74 79 6c ng.UTF8.DateStyl
0080 65 00 49 53 4f 00 54 69 6d 65 5a 6f 6e 65 00 50 e.ISO.TimeZone.P
0090 52 43 00 65 78 74 72 61 5f 66 6c 6f 61 74 5f 64 RC.extra_float_d
00a0 69 67 69 74 73 00 32 00 00 igits.2..
- s2. server 响应AuthOk, 发送ParameterStatus和ReadyForQuery
- AuthOk 'R': header - length = 0x52
- 一堆ParameterStatus 'S';
0040 52 00 00 00 08 00 00 00 00 53 00 00 00 16 R........S....
0050 61 70 70 6c 69 63 61 74 69 6f 6e 5f 6e 61 6d 65 application_name
0060 00 00 53 00 00 00 19 63 6c 69 65 6e 74 5f 65 6e ..S....client_en
0070 63 6f 64 69 6e 67 00 55 54 46 38 00 53 00 00 00 coding.UTF8.S...
0080 17 44 61 74 65 53 74 79 6c 65 00 49 53 4f 2c 20 .DateStyle.ISO,
0090 4d 44 59 00 53 00 00 00 19 69 6e 74 65 67 65 72 MDY.S....integer
00a0 5f 64 61 74 65 74 69 6d 65 73 00 6f 6e 00 53 00 _datetimes.on.S.
00b0 00 00 1b 49 6e 74 65 72 76 61 6c 53 74 79 6c 65 ...IntervalStyle
00c0 00 70 6f 73 74 67 72 65 73 00 53 00 00 00 14 69 .postgres.S....i
00d0 73 5f 73 75 70 65 72 75 73 65 72 00 6f 6e 00 53 s_superuser.on.S
00e0 00 00 00 19 73 65 72 76 65 72 5f 65 6e 63 6f 64 ....server_encod
00f0 69 6e 67 00 55 54 46 38 00 53 00 00 00 1a 73 65 ing.UTF8.S....se
0100 72 76 65 72 5f 76 65 72 73 69 6f 6e 00 38 2e 33 rver_version.8.3
0110 2e 32 33 00 53 00 00 00 20 73 65 73 73 69 6f 6e .23.S... session
0120 5f 61 75 74 68 6f 72 69 7a 61 74 69 6f 6e 00 75 _authorization.u
0130 73 65 72 31 00 53 00 00 00 23 73 74 61 6e 64 61 ser1.S...#standa
0140 72 64 5f 63 6f 6e 66 6f 72 6d 69 6e 67 5f 73 74 rd_conforming_st
0150 72 69 6e 67 73 00 6f 6e 00 53 00 00 00 11 54 69 rings.on.S....Ti
0160 6d 65 5a 6f 6e 65 00 50 52 43 00 4b 00 00 00 0c meZone.PRC.K....
0170 00 00 f3 0b 47 c8 22 c4 5a 00 00 00 05 49 ....G.".Z....I
- s3. client采用Extended Query,依次发送Parse Bind Describe execute 和sync
- Parse 'P': header - length=0x3b
- Bind 'B': header - length=0x0c
- Describe 'D': header - length=0x06
- Execute 'E': header - length=0x09
- Sync 'S': header - length=0x04
0040 50 00 00 00 3b 00 69 6e 73 65 72 74 20 69 P...;.insert i
0050 6e 74 6f 20 74 61 62 6c 65 31 20 76 61 6c 75 65 nto table1 value
0060 73 20 28 31 2c 20 31 31 20 2c 20 31 29 2c 20 20 s (1, 11 , 1),
0070 28 32 2c 20 20 32 32 2c 20 32 29 00 00 00 42 00 (2, 22, 2)...B.
0080 00 00 0c 00 00 00 00 00 00 00 00 44 00 00 00 06 ...........D....
0090 50 00 45 00 00 00 09 00 00 00 00 01 53 00 00 00 P.E.........S...
00a0 04 .
- s4. server依次响应ParseComplete,BindComplete,NoData,CommandComplete, 然后加一个ReadyForQuery;
- ParseComplete '1';
- BindComplete '2';
- NoData 'n';
- CommandComplete 'C';
- ReadyForQuery 'Z';
0040 31 00 00 00 04 32 00 00 00 04 6e 00 00 00 1....2....n...
0050 04 43 00 00 00 0f 49 4e 53 45 52 54 20 30 20 32 .C....INSERT 0 2
0060 00 5a 00 00 00 05 49 .Z....I