MySQL通讯协议(2)数据包

Wesley13
• 阅读 523

MySQL通讯协议(2)数据包

使用MySQL协议发送数据,有两个要求:

  • 将数据分成大小为(2^24−1)字节的数据包
  • 给每个数据块加上一个包头

由于连接的创建和释放都需要耗费资源,所以数据库这种交互频繁,且连接数量不需要特别大的应用场景,一般使用长连接。

使用短连接尚能通过RST判断数据是否读完了,而长连接就不能这么做了,同时由于TCP的特点,数据读写会发生拆包、粘包。所以使用长连接传输数据,必须通过某种方法把要发送的数据告诉接收方。例如HTTP协议head里的CONTENT-LENGTH。也可以通过特殊的符号判断,不过由于消息里可能也会出现这些符号,会发生歧义,所以应用场景受限。还有一种最简单的方法就是每次发送固定长度消息,不够用0填充。

MySQL数据包结构

Type

Name

Description

int<3>

payload_length

payload的长度,整数类型。不包括包头四个字节

int<1>

sequence_id

Sequence ID

string

payload

有效载荷,字符串类型。长度=payload_length

消息包分为两个部分,包头+包体。

包头固定四个字节,前三个字节是整数型的payload长度,第四个是整数型的消息序列号。

包体就是这个包的有效载荷,长度由前三字节指定,内容根据具体场景各不相同。

例如,一个消息为03 00 00 01 01 02 03 04。先读取前四个字节,发现这个消息包体有3个字节,这个消息序号是0,消息内容是01 02 03,后面的04是下一个包的数据。

包体长度

由于包体长度是由三个字节记录的,三个字节能表示的最大值为FF FF FF,即1<24-1=2^24-1=16777215=15.999...M。所以,一个MySQL消息包体不能超过16MB。如果超过16MB,就分多次发送。

消息序号

消息号用来标记每个消息的顺序,会自动增长,并循环。

通用响应包

对于大多数请求,服务端有一些通用的响应包结构。

OK_Packet

命令成功完成后的响消息。

Type

Name

Description

int<1>

header

[00][fe]

int

affected_rows

affected rows 影响行数

int

last_insert_id

last insert-id 最后插住数据id

if capabilities & CLIENT_PROTOCOL_41 {

int<2>

status_flags

Status Flags

int<2>

warnings

警告数量

} else if capabilities & CLIENT_TRANSACTIONS {

int<2>

status_flags

Status Flags

}

if capabilities & CLIENT_SESSION_TRACK {

string

info

容易理解的状态信息

if status_flags & SERVER_SESSION_STATE_CHANGED {

string

session_state_changes

session state info

}

} else {

string

info

容易理解的状态信息

}

header:表明这是一个OK还是EOF响应。

capabilities :在创建连接阶段,客户端和服务端交换的字段,用于表示支持哪些特性。

CLIENT_PROTOCOL_41:4.1+版本的客户端使用的协议。

ERR_Packet

Type

Name

Description

int<1>

header

[ff]

int<2>

error_code

错误码

if capabilities & CLIENT_PROTOCOL_41 {

string[1]

sql_state_marker

# marker of the SQL State

string[5]

sql_state

SQL State

}

string

error_message

容易理解的错误信息

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
2年前
tcp_tw_recycle参数引发的数据库连接异常
【问题描述】开发反馈有个应用在后端数据库某次计划性重启后经常会出现数据库连接异常问题,通过监控系统的埋点数据,发现应用连接数据库异常有两类表现:  其一:连接超时  <spanstyle"backgroundcolor:FFFF00"131148.00msTomcatConnectionPool</span  其二:连接耗时过
Wesley13 Wesley13
2年前
MySQL基础(一)
一、连接MySQL数据库1连接:2mysqlhhostuuserp34常见错误:5ERROR2002(HY000):Can'tconnecttolocalMySQLserverthroughsocket'/tmp/my
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
2年前
HikariCP
数据库连接池技术数据库连接池负责分配、管理和释放数据库的连接。1.数据库连接复用。重复使用现有的数据库连接,可以避免连接频繁建立、关闭的开销。2.统一的连接管理。释放空闲时间超过最大空闲时间的数据库连接,避免因为没有释放数据库连接而引起的数据库连接泄漏。HikariCP字节码精简:优化代码,直到编译后的字节码最少
Wesley13 Wesley13
2年前
thinkphp 基本配置
12returnarray(34//定义数据库连接信息5'DB\_TYPE''mysql',//指定数据库是mysql67'DB\_HOST''localhost',89'DB\_NAME''uchome',//数据库名1011'DB\_USER''root
Wesley13 Wesley13
2年前
34.TCP取样器
阅读文本大概需要3分钟。1、TCP取样器的作用   TCP取样器作用就是通过TCP/IP协议来连接服务器,然后发送数据和接收数据。2、TCP取样器详解!(https://oscimg.oschina.net/oscnet/32a9b19ba1db00f321d22a0f33bcfb68a0d.png)TCPClien
Stella981 Stella981
2年前
Linux应急响应(二):捕捉短连接
0x00前言​短连接(shortconnnection)是相对于长连接而言的概念,指的是在数据传送过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。在系统维护中,一般很难去察觉,需要借助网络安全设备或者抓包分析,才能够去发现。0x01应急场景​