04_mysql文本协议

本文详细解析了MySQL中的COM_QUERY命令及其响应,包括OK_Packet、ERR_Packet报文,以及create、insert、update、delete语句的响应。此外,还介绍了resultSet结果集、列数据类型、列定义、文本结果集行等内容,深入理解MySQL协议交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

只挑选几个重点命令讲解

1 COM_QUERY

COM_QUERY用于向服务器发送立即执行的基于文本的查询。

报文结构:

3 bytes 报文长度1 byte 序号1 byte 命令n bytes 参数

包体部分:
- command_id ( 1 ):0x03 COM_QUERY
- query ( string.EOF ):query_text

查询字符串的长度取自数据包长度-1。

报文实例:
image

2 COM_QUERY响应

COM_QUERY响应报文可能是:
1. ERR_Packet报文
2. OK_Packet报文
3. Protocol::LOCAL_INFILE_Request (本文不介绍该报文)
4. ProtocolText::Resultset

2.1 何时返回OK_Packet和ERR_Packet报文

如果SQL是create、insert、update或者是delete,则返回的是对应的OK_Packet或者ERR_Packet报文。

2.1.1 create语句返回报文

sql语句:

CREATE TABLE test(
id int auto_increment primary key,
type_char char(10) DEFAULT NULL
);

create语句报文:
create_sql

create语句响应报文:
create_sql_response

语句执行成功,返回OK_Packet,蓝色部分为mysql协议报文,第5字节0x00表示OK_Packet,第6个字节表示影响行数。

2.1.2 insert语句返回报文

sql语句:

insert into test(type_char) values('test_value');

insert语句报文:
insert_sql

insert语句响应报文:
insert_sql_response

语句执行成功,返回OK_Packet,蓝色部分为mysql协议报文,第5字节0x00表示OK_Packet,第6个字节表示影响行数,第7个字节表示insert id。

2.1.3 update语句返回报文

sql语句:

update test set type_char='update' where id=1;

update语句报文:
update_sql

update语句响应报文:
update_sql_response

语句执行成功,返回OK_Packet,蓝色部分为mysql协议报文,第5字节0x00表示OK_Packet,第6个字节表示影响行数。

2.1.4 delete语句返回报文

sql语句:

delete from test where id=1;

delete语句报文:
delete_sql

delete语句响应报文:
delete_sql_response

语句执行成功,返回OK_Packet,蓝色部分为mysql协议报文,第5字节0x00表示OK_Packet,第6个字节表示影响行数。

2.1.5 ERR_Packet报文

当客户端删除一个不存在表的数据的时候,客户端后收到ERR_Packet报文。

delele from test_delete;

ERR_Packet报文:
ERR_Packet

2.2 resultSet结果集

  1. column_count数据包: 第一个包包含一个Protocol::LengthEncodedInteger类型整数,表示列数

  2. ColumnDefinition数据包:结果集列定义,有column_count个Protocol::ColumnDefinition数据包

  3. EOF_Packet:如果CLIENT_DEPRECATE_EOF客户端能力标志未设置,那么是一个EOF_Packet数据包

  4. ResultsetRow数据包:一个或多个ProtocolText::ResultsetRow数据包,每个包含column_count值

  5. ERR_Packet/EOF_Packet/OK_Packet:发生错误是ERR_Packet数据包; 另外:如果设置了CLIENT_DEPRECATE_EOF客户端能力标志是OK_Packet数据包,否则是EOF_Packet数据包。

如果在最后一个EOF_Packet或者OK_Packet中设置了SERVER_MORE_RESULTS_EXISTS标志(如果设置了CLIENT_DEPRECATE_EOF能力标志就是OK_Packet), 将会跟随另一个ProtocolText::Resultset (请参阅多结果集)。

resultrow

2.2 列数据类型

请参考:https://dev.mysql.com/doc/internals/en/com-query-response.html#text-resultset

2.3 列定义

lenenc_str     catalog
lenenc_str     schema
lenenc_str     table
lenenc_str     org_table
lenenc_str     name
lenenc_str     org_name
lenenc_int     length of fixed-length fields [0c]
2              character set
4              column length
1              type
2              flags
1              decimals
2              filler [00] [00]
  if command was COM_FIELD_LIST {
lenenc_int     length of default-values
string[$len]   default values
  }

字段说明:

  • catalog (lenenc_str) :目录,值总是为def

  • schema (lenenc_str) : schema名称

  • table (lenenc_str) :虚拟表名

  • org_table (lenenc_str) :物理表名

  • name (lenenc_str) :虚拟列名

  • org_name (lenenc_str) :物理列名

  • next_length (lenenc_int): 以下字段的长度(始终为0x0c )

  • character_set (2) :是列字符集,并在Protocol::CharacterSet中定义

  • column_length (4):字段的最大长度

  • column_type (1):列类型中定义的列的类型

  • flags (2) :flags

  • decimals (1) :最大显示十进制数字

    整数和静态字符串为0x00

    动态字符串,double,float为0x1f

    小数位为0x00至0x51

注意:decimals和column_length可用于文本输出格式。

2.4 文本结果集行

一个ProtocolText :: ResultsetRow包含一行与每列的数据。

NULL表示为0xfb。

一切都转换成一个字符串,并作为Protocol::LengthEncodedString发送。

2.5 实例

语句:

select 1

wireshark解析的报文:
image

wireshark捕获的二进制报文:
image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值