彻底弄懂mysql(一)--mysql的通信协议

我准备从mysql的实现出发,将mysql好好理解一下,从他的逻辑结构一层一层出发,感受一下,所以再学第一层之前,要先对mysql整体的逻辑结构有一个初步认识

mysql逻辑架构

在这里插入图片描述
整体来说,MySql的逻辑架构分成三个部分,这个之前我以为提到过
1)客户端:主要是建立连接的过程,交互的过程
2)核心服务
3)存储引擎

这个可能比较抽象,我们结合MySql的查询过程,结合着进行学习

MySql查询过程

在这里插入图片描述
这个图其实就是在第一个的基础上,进行的更加细致的划分,因为上面只是大致画出了逻辑架构,但是这个就展示了一整个过程。

我说一下大致的过程:

1)客户端向服务端发起一条请求
2)服务端先检查查询缓存,如果命中缓存,则直接返回结果,否则交给下一阶段
3)服务器进行SQL解析,预处理,在经过查询优化形成对应的执行计划
4)mysql根据执行计划,调用API给存储引擎,进行数据的读取和存储
5)将结果返回给客户端,并缓存查询结果

大致整体的步骤就是这样的,我们要把每一步都尽量的深入思考下,我可能考虑的有欠缺,欢迎大家进行留言

今天先不深入数据库里面,先将mysql的通信协议搞清楚,也就是执行sql语句之前都干了什么

要了解mysql通信协议,就要知道mysql是通过什么连接的,这个怎么考率的,mysql是应用,我们需要实现的是mysql客户端与服务端进行通信,这里好比http,所以在客户端找到服务端之前,就需要他们所处的物理机先建立起连接,就如同http建立连接之前,需要tcp先建立连接。

Mysql的主要连接方式包括:Unix套接字,内存共享,命名管道,TCP/IP套接字等。

有的同学可能问了,怎么这么多方式,那我用的哪一种呢,或者是我应该用哪一种呢,其实他们并不是等价的

Unix套接字:

在Linux和Unix环境下,可以使用Unix套接字进行Mysql服务器的连接;Unix套接字其实不是一个网络协议,只能在客户端和Mysql服务器在同一台电脑上才可以使用

命名管道和内存共享

在window系统中客户端和Mysql服务器在同一台电脑上,可以使用命名管道和共享内存的方式,
命名管道开启:–shared-memory=on/off;
共享内存开启:–enable-named-pipe=on/off;

TCP/IP套接字

任何系统下都可以使用的方式,也是使用的最多的方式,我主要介绍的也是这种方式

其实熟悉操作系统的朋友应该能体会出来,像前两种,因为客户端和服务端在同一台主机上,也就是一台主机的两个应用,所以这也就是进程间通信的方式,而在不同的主机上就不一样了,就需要网络,tcp/ip建立了。

mysql通信过程

了解了mysql基于的就是tcp的底层协议,所以必然,需要经历tcp的三次握手,没错第一步就是tcp的三次握手(因为这里不是重点,就不详细说明,不太清楚的同学,可以查看我network的相关博客),建立连接之后就可以发送sql命令了吗,当然不能,细心的同学会发现,我用客户端登陆的时候,是需要用户名,密码的,这才是真正的mysql客户端与服务端的交互过程,之前还没有到应用层,下面就说一下,交互过程

mysql客户端与服务端的交互过程

主要分为两部分:握手认证阶段,命令执行阶段
注意哦,这个握手和上面过的握手不一样哦

1.1握手认证阶段

握手认证阶段为客户端与服务器建立连接后进行,交互过程如下:
服务器 -> 客户端:握手初始化消息
客户端 -> 服务器:登陆认证消息
服务器 -> 客户端:认证结果消息

1.2命令执行阶段

客户端认证成功后,会进入命令执行阶段,交互过程如下:
客户端 -> 服务器:执行命令消息
服务器 -> 客户端:命令执行结果
在这里插入图片描述
不知道大家看了有没有产生一些问题,那我就我的一些问题说一下

为什么还要进行三次握手认证

因为tcp三次握手,只是将客户端与服务端建立起了连接,然后通过端口知道我要访问的是mysql这个服务,但是mysql它不同于http,只要你知道url就能得到一个响应,mysql必须登陆后你才能进行操作。所以这个过程最重要的就是验证客户端的登陆权限。

为什么是服务端主动给客户端发送认证呢?

http不是说只有客户端主动与服务端进行请求,服务端不是不能在没有请求的情况下主动进行响应吗?
首先,大家也不要陷入误区,在进行认证的这个交互中,实际上客户端与服务端还没有进行任何业务上的往来,只是进行一个认证,所以与上面说的http的不同,如果细心的话你会发现,认证成功后,在命令执行阶段,mysql这种通信方式是与http非常类似的,在没有请求的情况下,服务端的mysql也不会主动给你发送任何数据,所以这里不要混淆。
再说为什么服务端先发送,那肯定是因为他有不得不发送的道理,所以我们就需要理解一下,他发送的是什么东西。

mysql报文

主要分成三个部分:登录认证报文,客户端请求报文以及服务器端返回报,基于mysql5.1.73(mysql4.1以后的版本)

登陆认证报文

1)握手初始化报文(服务端->客户端)
在这里插入图片描述
协议版本号:服务端所使用的mysql协议的版本号
服务器线程ID:服务端为此客户端所创建的线程的ID
挑战随机数:MySQL数据库用户认证采用的是挑战/应答的方式,服务器生成该挑战数并发送给客户端,由客户端进行处理并返回相应结果,然后服务器检查是否与预期的结果相同,从而完成用户认证的过程。
**服务器权能标志:**用于与客户端协商通讯方式
这个我稍微解释下,他这个只要发送的就是,我服务端能接受的通讯方式是什么样的,我们下面详细说一下

登陆认证报文(客户端 -> 服务器)

在这里插入图片描述
客户端权能标志客户端收到服务器发来的初始化报文后,会对服务器发送的权能标志进行修改,保留自身所支持的功能,然后将权能标返回给服务器,从而保证服务器与客户端通讯的兼容性。
消息长度客户端发送请求时所支持的最大消息长度值
字符编码表示通讯过程中使用的字符编码,与服务器在认证报文中发送的相同
用户名客户端登陆的用户名
挑战认证数据:客户端用户密码使用服务器发送的挑战随机数进行加密后,生成挑战认证数据,返回给服务器用于服务端的认证

服务端认证结果报文(服务端->客户端)

这个就比较好理解了,服务端主要验证,用户名,密码是否正确存在,如果都是正确的,就返回ok报文,错误的话就是ERROR报文

好了,我相信大家应该都有一定的了解了,那么现在再想一下那个问题是不是觉得是非常有道理的,之所以服务端先发送一个握手过去,就是提前通知一下客户端,你要遵循的一些协议
举个例子:
小明找工作,投了一个简历给某个公司
这时候,某公司就主动打电话了,告诉他,我们需要笔试,笔试的时间,网址,以及一些别的相关信息,规则等

小明接收到这个消息之后,到了那个时间他就会请求那个网址,并将自己的信息告诉他

这时候公司验证你的信息,验证成功后,你就可以开始笔试了

大家可以类比这理解一下,就能体会出,这是非常有必要的。

这一章先讲这么多,下一张我们讲一下,挑战随机数和全能标志位的原理,有兴趣的同学可以关注一下,有问题也可以随时交流。

猜你喜欢

转载自blog.csdn.net/LYue123/article/details/89256577