Packet基本构成
- Packet不能超过16M(224-1 byte,0xffffff),如果超过了会拆成多个Packet发送
- Packet头部都必须携带Header信息
Packet拆解
- Header信息由4个字节组成,前3字节代表mysql包长度(payload_length),第4字节表示包序号(sequence_id)
- 从第5个字节开始表示mysql包内容(payload),具体长度由payload_length决定
举个例子,Packet用字节数组表示:49 1 0 0 2 50 22…………
- payload_length = 305
- sequence_id = 0
payload_length 计算逻辑如下:
byte[] buf= new byte[3];
buf[0] = 49;
buf[1] = 1;
buf[2] = 0;
payload_length = (0xff & buf[position]) | ((0xff & buf[position + 1]) << 8) | ((0xff & buf[position + 2]) << 16);
mysql包大小超过16M的情况
前面讲过payload大小必须<= 224-1(FF FF FF), 假设现有payload大小等于224,那么会被拆成2次发送:
FF FF FF
00 00 01
sequence_id 说明
sequence_id表示一个完整流程的包序号,从0开始,当有拆包或者回复包都会往上+1。新的流程会重新从0开始。
Client发送的命令类型
命令类型由第5个字节表示:
命令类型具体有哪几种,可以参考官方文档:https://dev.mysql.com/doc/internals/en/command-phase.html
Server返回给Client的Packet格式
Server返回的Packet有3种类型:OK_Packet、ERR_Packet、EOF_Packet
- OK_Packet:表示Client发送的命令执行成功,第1个字节值等于 00
- ERR_Packet:表示发生异常,第1个字节值等于 FF
- EOF_Packet:在MySQL 5.7.5版本弃用了,作用和OK_Packet类似,第1个字节值等于 FE,可以不用管。