MySQL网络协议分析
本篇文章向大家介绍《MySQL网络协议分析》,主要包括网络编程、MySQL、网络传输协议,具有一定的参考价值,需要的朋友可以参考一下。
MySQL对大家来说,都应该很熟悉了,从大学里的课程到实际工作中数据的存储查询,很多时候都需要用到数据库,很多人也写过与数据库交互的程序,在Java中你可能一开始会使用原生mysql-connector-java来进行操作,后来你会接触到Hibernate,Mybatis等ORM框架,其实它们底层也是基于mysql-connector-java,但很多时候我们并不清楚程序是怎么跟数据库具体交互的,比如执行一个SQL查询,程序是如何从MySQL中获取数据的呢?今天就让我们来看看最基础的MySQL网络协议分析。
引言
阅读本文之前你需要对网络协议需要有基本的了解,比如两台机子之间的数据是如何通信的,硬件层可以暂时不需了解,但网络层和传输层的协议要有一定的理解,比如IP数据包,TCP/IP协议,UDP协议等相关概念,有了这些基础,有利于你阅读本文。
背景
在历史悠久的时代,数据库只作为单机存储,也不怎么需要与程序进行交互的时候的首,它的网络通信并不是那么重要,但随着时代的发展,数据库不再只是单纯的作为一个数据的仓库了,它需要提供与外界的交互,比如远程连接,程序操作数据库等,这时候一份规范的网络通信的协议就非常重要了,比如它是如何校验权限,如何解析SQL语句,如何返回执行结果都需要用到相应的协议,很多时候我们并不需要接触这些内容,因为它太底层了,我们直接使用把它们封装好的第三方包就可以了,为什么还要去学习它的网络协议呢?确实对于一开始学习编程的人来说,这有点操之过急,反而有时候会适得其反,但当你对这一方面有了一定的了解之后,你便会迫不及待得想去探索更深层的奥秘,去了解并学习我们平常用的第三方类库是怎么去实现,明白它的底层原理,甚至对一些莫名其妙的bug也不会再害怕。
MySQL连接方式
分析协议,我们首先要了解如何与数据库连接,说到MySQL连接方式,大家突然可能有点懵,其实它一直伴随着我们,比如我们第一次装数据库完成后执行的第一次登录,比如你没有设置密码:
mysql -uroot
这是最基本的一种数据库连接方式,那么MySQL连接方式到底有几种呢?到MySQL5.7为止,总共有五种,分别是TCP/IP,TLS/SSL,Unix Sockets,Shared Memory,Named pipes,下面我们就来看看这五种的区别:
方式 | 默认开启 | 支持系统 | 只支持本机 | 如何开启 | 参数配置 |
---|---|---|---|---|---|
TCP/IP | 是 | 所有系统 | 否 | --skip-networking=yes/no. | --port --bind-address |
TLS/SSL | 是 | 所有系统(基于TCP/IP)之上 | 否 | --ssl=yes/no. | --ssl-* options |
Unix Sockets | 是 | 类Unix系统 | 是 | 设置--socket= |
--socket=socket path |
Shared Memory | 否 | Windows系统 | 是 | --shared-memory=on/off. | --shared-memory-base-name= |
Named pipes | 否 | Windows系统 | 否 | --enable-named-pipe=on/off. | --socket= |
从上表中我们可以清晰看出每种连接方式的区别,接下里我会具体说明几种连接是怎么操作的,由于我的机子是Mac OS系统,这里只模拟非Windows系统下的三种方式,因为这三种方式都是默认开启的,我们不需要进行任何配置:
1.Unix Sockets:
mysql -uroot
若你在本机使用这种方式连接MySQL数据库的话,它默认会使用Unix Sockets。
2.TCP/IP:
mysql --protocol=tcp -uroot mysql -P3306 -h127.0.0.1 -uroot
连接的时候我们指定连接协议,或者指定相应的IP及端口,我们的连接方式就变成了TCP/IP方式。
3.TLS/SSL:
mysql --protocol=tcp -uroot --ssl=on mysql -P3306 -h127.0.0.1 -uroot --ssl=on
上表说过,TLS/SSL是基于TCP/IP的,所以我们只需再指定打开ssl配置即可。
然后我们可以通过以下语句来查询目前数据库的连接情况:
SELECT DISTINCT connection_type from performance_schema.threads where connection_type is not null
那么我们如何选择连接方式呢?个人总结了以下几个原则:
- 若是你能确定程序和数据库在同一台机子(类Unix系统)上,推荐使用Unix Sockets,因为它效率更高;
- 若数据库分布在不同的机子上,且能确保连接安全或者安全性要求不是那么高,推荐使用TCP/IP,反之使用TLS/SSL;
MySQL数据包
通信中最重要的就是数据,那么程序是如何和MySQL Server进行通信,并交互数据的呢?比如如何验证账户,发送查询语句,返回执行结果等,我先画一个流程图来模拟一下整个过程,帮助大家理解:

整个过程相对来说还是比较清晰的,我们对连接请求和断开请求不需要过分关心,只需要了解这一点就可以了,重要的是其他几点,那么在这几步中,数据是怎么进行交互的呢?
其实主要就是两步,Client将执行命令编码成Server要求的格式传输给Server端执行,Server端将执行结果传输给Client端,Client端再根据相应的数据包格式解析获得所需的数据。
1.基本数据类型
虽然网络中的数据是用字节传输的,但它背后的数据源都是有类型的数据,MySQL协议也有基本的数据类型,好比Java中的8种基本数据类型,但MySQL协议中简单的多,它只有两种基本数据类型,分别为Integer(整型),String(字符串),下面我们就来看看这两种类型。
Integer(整型)
首先Integer在MySQL协议中有两种编码方式,分别为FixedLengthInteger和LengthEncodedInteger
,其中前者用于存储无符号定长整数,实际中使用的不多,这里着重讲一下后者。
使用LengthEncodedInteger编码的整数可能会使用1, 3, 4, 或者9 个字节,具体使用字节取决于数值的大小,下表是不同的数据长度的整数所使用的字节数:
最小值(包含) | 最大值(不包含) | 存储方式 |
---|---|---|
0 | 251 | 1个字节 |
251 | 2^16 | 3个字节(0xFC + 2个字节具体数据) |
2^16 | 2^24 | 4个字节(0xFD + 3个字节具体数据) |
2^24 | 2^64 | 9个字节(0xFE + 8个字节具体数据) |
举个简单的例子,比如1024的编码为:
use godpan
相应的报文格式则为:
PreparedStatement ps = connection.prepareStatement("SELECT * FROM `godpan_fans` where id=?"); ps.setInteger(1, 1); ps.executeQuery();
得到下面的PREPARE_OK包,仅供参考:
PSOK{statementId=1, columns=5, parameters=1}
如果上面的columns大于0,以及parameters大于0,则将有额外的两个包传输,分别是columns的信息以及parameters的信息,对应信息结构:
内容 | 含义 |
---|---|
Field | columns信息(多个) |
EOF | columns信息结束 |
Field | parameters(多个) |
EOF | parameters结束 |
到此整个PREPARE_OK包发送完毕。
Row Data Binary
这个包跟上面提到的Row Data包有什么差别呢?主要有两点:
- 用不同的方式定义NULL;
- 数据编码不再单纯的使用LengthEncodedString,而是根据数据类型的不同进行相应的编码;
后面我会分别解释这两点,我们先来看看它的结构:
相对包内容的位置 | 长度(字节) | 名称 | 描述 |
---|---|---|---|
0 | 1 | 包头标识 | 0x00 |
1 | (col_count+7+2)/8 | Null Bit Map | 前两位为预留字节,主要用于区别与其他的几种包(OK,ERROR,EOF),在MySQL 5之后这两个字节都为0X00,其中col_count为列的数量 |
(col_count+7+2)/8 + 1 | n | column values | 具体的列值,重复多次,根据值类型编码 |
现在我们来看一下它的两个特点,首先我们来看它是如何来定义NULL的,首先我们看到他的结构中有一个Null Bit Map,除去两个标识位,真正用于标识数据信息的就是(col_count+7)/8位字节,这里我先给出结论,后面再给大家具体分析:
参数个数 | 长度(字节) | 具体值范围 | 描述 |
---|---|---|---|
1-8 | 1 | -1, 2^n组合 | 1 = 2^0表示第一个参数为NULL,3 = 2^0 + 2^1表示第一个和第二参数为NULL... |
上面给出了标识NULL的基本算法,原则是哪个参数(次序为n)为NULL,则Null Bit Map相应的值加上2^n,8个参数为一个周期,以此类推。
接着我们来看一下第二点,是如何用具体值类型来对相应的值进行编码的,这里主要分为三类,基本数据类型,时间类型,字符串类型;
- 基本数据类型:比如TINYINT使用一个字节编码,FLOAT使用四个字节,DOUBLE使用8个字节等;
- 时间类型:使用类似LengthEncodedString的编码方式编码,具体可参考MySQL_PROTOCOL;
- 字符串类:不属于上面两类的都属于字符串类型,使用普通的LengthEncodedString;
Execute包
Execute包顾名思义是一个执行包,它是由Client端发送到Server端的,但它和普通的命令又有点不同,它主要是用来执行预处理语句,并会携带相应参数,具体结构如下:
长度 | 含义 |
---|---|
1 | COM_EXECUTE(标识是一个Execute包) |
4 | 预处理语句id |
1 | 游标类型 |
4 | 预留字节 |
0 | 接下去的内容只有在有参数的情况下 |
(param_count+7)/8 | null_bit_map(描述参数中NULL的情况) |
1 | 参数绑定情况 |
n*2 | 参数类型(依次存储) |
n | 参数具体值(非NULL)(依次存储,使用Row Data Binary方式编码) |
Execute包从Client端发送到Server端后可能会得到以下几个结果:
- OK包
- ERROR包
- Result Set包(可能多个)
我们需要根据包的不同类型来进行不同的处理。
总结
本篇文章主要讲述了MySQL的连接方式,通信过程及协议,以及传输包的基本格式和相关传输包的类型,内容相对来说,比较多也比较复杂,我也是将近三周才写完,但总体按照我自学的思路走,不会太绕,有些点可能需要细心思考下,写的有误的地方也希望大家能指正,希望对大家有所帮助,后面可能会写几个实例和大家一起学习。
好了,本文到此结束,带大家了解了《MySQL网络协议分析》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多数据库知识!

- 上一篇
- MySql Binlog初识

- 下一篇
- MySQL中索引和视图
-
- 要减肥的黑猫
- 很详细,mark,感谢博主的这篇技术文章,我会继续支持!
- 2023-03-27 05:18:06
-
- 单纯的故事
- 这篇技术文章真是及时雨啊,细节满满,真优秀,码起来,关注楼主了!希望楼主能多写数据库相关的文章。
- 2023-03-15 12:47:23
-
- 忧伤的路人
- 写的不错,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢老哥分享博文!
- 2023-02-02 06:57:16
-
- 机智的鸡
- 这篇文章内容真是及时雨啊,作者大大加油!
- 2023-01-21 11:29:52
-
- 数据库 · MySQL | 35分钟前 | mysql 性能优化 备份恢复 CREATEDATABASE 本地开发环境
- mysql本地数据库创建及开发环境搭建指南
- 218浏览 收藏
-
- 数据库 · MySQL | 9小时前 | explain SHOW FLUSH CHECKTABLE
- 揭秘MySQL内部命令与系统级管理技巧
- 349浏览 收藏
-
- 数据库 · MySQL | 12小时前 | 索引 数据类型 扩展性 约束 AUTO_INCREMENT
- MySQL建表语句详解与编写攻略
- 329浏览 收藏
-
- 数据库 · MySQL | 16小时前 |
- MySQL中AS关键字别名功能详解
- 244浏览 收藏
-
- 数据库 · MySQL | 17小时前 |
- MySQL新手必备基础命令及操作指南
- 457浏览 收藏
-
- 数据库 · MySQL | 20小时前 | jdbc 性能优化 连接池 MySQLConnector/Python mysql2
- MySQL数据库连接技巧与常见问题攻略
- 466浏览 收藏
-
- 数据库 · MySQL | 22小时前 |
- 解析MySQL数据库特性与优势,深入浅出
- 228浏览 收藏
-
- 数据库 · MySQL | 22小时前 | 表结构 索引优化 降序排序 DESC SHOWCREATETABLE
- MySQL中desc用法:降序排序及表结构查看
- 268浏览 收藏
-
- 数据库 · MySQL | 23小时前 |
- MySQL数据库深度解析:特性与优势详解
- 200浏览 收藏
-
- 数据库 · MySQL | 23小时前 | 备份 DROPTABLE TRUNCATETABLE IFEXISTS 外键检查
- MySQL详解droptable命令及表结构删除
- 207浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 魔匠AI
- SEO摘要魔匠AI专注于高质量AI学术写作,已稳定运行6年。提供无限改稿、选题优化、大纲生成、多语言支持、真实参考文献、数据图表生成、查重降重等全流程服务,确保论文质量与隐私安全。适用于专科、本科、硕士学生及研究者,满足多语言学术需求。
- 17次使用
-
- PPTFake答辩PPT生成器
- PPTFake答辩PPT生成器,专为答辩准备设计,极致高效生成PPT与自述稿。智能解析内容,提供多样模板,数据可视化,贴心配套服务,灵活自主编辑,降低制作门槛,适用于各类答辩场景。
- 30次使用
-
- Lovart
- SEO摘要探索Lovart AI,这款专注于设计领域的AI智能体,通过多模态模型集成和智能任务拆解,实现全链路设计自动化。无论是品牌全案设计、广告与视频制作,还是文创内容创作,Lovart AI都能满足您的需求,提升设计效率,降低成本。
- 32次使用
-
- 美图AI抠图
- 美图AI抠图,依托CVPR 2024竞赛亚军技术,提供顶尖的图像处理解决方案。适用于证件照、商品、毛发等多场景,支持批量处理,3秒出图,零PS基础也能轻松操作,满足个人与商业需求。
- 37次使用
-
- PetGPT
- SEO摘要PetGPT 是一款基于 Python 和 PyQt 开发的智能桌面宠物程序,集成了 OpenAI 的 GPT 模型,提供上下文感知对话和主动聊天功能。用户可高度自定义宠物的外观和行为,支持插件热更新和二次开发。适用于需要陪伴和效率辅助的办公族、学生及 AI 技术爱好者。
- 38次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览