转载地址:https://dev.mysql.com/doc/dev/mysql-server/8.0.0/page_protocol_basic_packets.html
一、packet意思
packet并不是mysql的procotol(协议),而是如何将协议数据准确发送甚至如何拆分过长的协议数据的更下层的支持。
二、packet结构
| length(3-bytes) | sequence-id(1-byte) | payload(length-bytes) |
length : payload的字节长度
sequence-id : packet的序列号,每一个新的mysql的command会重置为0,过长的协议数据,会拆分成多个packet,而顺序则是由这个sequence-id来顺序指定
payload : 实际procotol(协议)的数据,如果小于16M,那么该payload就是整个command的协议数据,否则会将procotol数据拆分成多个packet
三、packet限制
1.一个packet最大能发送16MB,即对于protocol的数据小于16MB,可以一个packet发送完
2.如果packet大于16MB,则会进行拆分,会拆分如下,即多个拆分除最后一个,之前均会是ff ff ff,直到遇到小于ff ff ff,而sequence-id,则会组装最终procotol协议数据作为依据:
ff ff ff 00 .......
00 00 00 01 .....
四、mysql服务端源码处理函数入口
1.有兴趣查看代码的话,对完整packet的数据读取和对多个packet进行组装的函数为
[sql/net_serv.cc] : ulong my_net_read(NET *net),如下图:
五、浅析mysql的protocol例子
当读取完所有packet,并且组装成最终的protocol协议数据后,便可以读区payload内部协议相关的数据了
protocol的数据结构:
| cmd(1-byte) | payload(length - 1 bytes) |
cmd : 实际协议的protocol的命令,包括:
payload : 则会是具体cmd的数据结构
如以COM_INIT_DB(如使用use DBName指令后):
其cmd为02,payload(dbname)为string[EOF]:
可能的完整packet:
0500 00 00 02 74 65 73 74
length : 5
sequence-id: 0
cmd : 02(COM_INIT_DB)
db_name : 0x74 0x65 0x73 0x74
相关转载链接:
https://dev.mysql.com/doc/internals/en/text-protocol.html
https://dev.mysql.com/doc/internals/en/com-init-db.html