前言
1,打开mysql genneral log
2,使用tcpdump命令查看网络协议
sudo tcpdump -i lo0 -X -vv src host 127.0.0.1 and port 3306
其中
- -i参数指定了 网卡名称;
- -X 参数抓取的报文抛弃了数据链路层数据报头,从ip层开始
分析
mysql package基本格式
无论是客户端->mysql服务器的命令请求包(command packet),还是mysql服务器->客户端的响应报文(response packet).格式如下:
Type | Name | Length | Description |
---|---|---|---|
int<3> | payload_length | 3个字节长度 | mysql报文数据体的长度,所以长度最大为 224−1 个字节 |
int<1> | sequence id | 序列号 | 请求包command packat总是以0开始,而响应包 response packet 则以1开始,根据该字段可以区分一个packet是客户端请求,还是服务器响应 |
string < var > | payload | payload_length | [len=payload_length] payload of the packet |
譬如:
01:19:00.520202 IP (tos 0x8, ttl 64, id 12987, offset 0, flags [DF], proto TCP (6), length 68, bad cksum 0 (->9ef)!)
localhost.52284 > localhost.mysql: Flags [P.], cksum 0xfe38 (incorrect -> 0x898e), seq 432:448, ack 4371, win 12601, options [nop,nop,TS val 1034419546 ecr 1034419546], length 16
0x0000: 4508 0044 32bb 4000 4006 0000 7f00 0001 E..D2.@.@.......
0x0010: 7f00 0001 cc3c 0cea 00a0 a787 2265 78df .....<......"ex.
0x0020: 8018 3139 fe38 0000 0101 080a 3da7 fd5a ..19.8......=..Z
0x0030: 3da7 fd5a 0c00 0000 0373 686f 7720 7461 =..Z.....show.ta
0x0040: 626c 6573 bles
剥离ip和tcp协议头,0c00 0000 0373 686f 7720 7461 626c 6573:
其中
0x0030: **** **** 0c00 0000 0373 686f 7720 7461 =..Z.....show.ta
0x0040: 626c 6573 bles
0c 00 00 //代表mysql packet的payload_length = 0x0c 即12个字节
00 //sequence id == 0(一般是command 客户端->服务器的开始sequence id, In the command phase, the client sends a command packet with the sequence-id [00])
03 //command type,参考 https://dev.mysql.com/doc/internals/en/command-phase.html
73 686f 7720 7461 626c 6573 //命令的参数,此处翻译为ascii码为 "show tables"
参考
1, https://dev.mysql.com/doc/internals/en/command-phase.html
2,[深入理解Mysql核心技术] 第四章:客户端/服务器通信