zxdsb666. 发表于 2022-3-18 23:23

"三高"Mysql - Mysql的基础结构了解

本帖最后由 zxdsb666. 于 2022-3-19 10:33 编辑

# "三高"Mysql - Mysql的基础结构了解

# 引言

​      内容为****的**《高并发 高性能 高可用 MySQL 实战》**视频的学习笔记内容和个人整理扩展之后的笔记,在快速视频学习一遍之后发现了许多需要补充的点,比如三次握手的连接和Mysql的内部交互流程等等,关于后续的章节也会整合多篇文章后续会陆续发布。



# Mysql的连接方式

​      使用最多的方式是第一种方式,另外三种方式受限于特殊的平台方式实现,重点掌握第一种TCP/IP的方式即可。

1. tcp/ip的连接形式
2. 共享内存的连接方式
3. 命名空间模式
4. unix套接字的连接方式



## Tcp/ip的通讯协议

​      这一块在视频中讲解比较浅,所以这里参考了多方资料后,以**《TCP/IP协议》**作为参考介绍三次握手和四次挥手的过程。

​      通讯协议也就是我们常见的三次握手和四次挥手的流程,注意这里忽略TCP/IP报文的格式介绍。

+ SYN:同步序号。
+ FIN:发送方完成标记。
+ ACK:仅当ACK=1时,确认号字段才有效,并且建立TCP连接之后所有的连接必须ACK=1。
+ ack:接受请求之后将请求序列号+1进行回送使用。
+ ISN:起始序号也别叫做Seq,该序号由时间决定,所以每一个Tcp都有一个唯一的起始序号,组成的方式是**开始的序号、一个冒号、隐含的结尾序号** 及圆括号内的数据字节数,比如1415531521:1415531521(0),如果字节为0则被隐藏,只有当存在字节数据或者SYN、 FIN 或 RST 被设置为 1 才进行展示。
+ Mss:表示的是当前报文的最大字节数。

>ISM可看作是一个32比特的计 数器,每 4ms + 1。




### 三次握手建立TCP连接(报问段1-3)

- 第一步:客户端主动打开TCB端口,服务器被动打开TCB端口。发起方携带一个SYN标志,并且携带一个ISN序号Seq=x,但是需要注意的是第一步的过程这个ISN序号是隐藏传递的(因为没有传递数据),但是如果不存在数据的交换,则不会被显示。客户端发送SYN命令之把**SYN=1**,并且把SYN-SENT(同步-已发送状态)。
- 第二步:服务器收到客户端TCP报文之后,也将SYN=1,并且回送一个新的ISN序号ack=x+1,并且将ACK=1表示自己收到了,然后在返回参数回送自己新的序列号表示自己的确认请求Seq=y,将状态设置为SYN-RCVD(同步收到)状态,(表示希望收到的序号为xxxx1522),最后也是指定MSS。
- 第三步:客户端收到服务器的确认报文之后,还需要向服务端返回确认报文,确认报文的ACK=1,并且回传服务器传递的ISN序号+1(ack = y+1),以及自己的ISN序号+1(Seq = x+1),此时TCP连接进入已连接状态,ACK是可以携带数据的,但是如果不携带数据则不消耗序列号。
- 最后一步:当服务器收到客户端的确认,也进入已连接状态。
![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20220318200850.png)

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20220318200826.png)

### Mysql认证连接:

(参考资料:(http://mysql.taobao.org/monthly/2018/08/07/))

​      Mysql的认证链接可以看作是三次交互,注意第一次请求是服务端发起的,有点类似我们去店里面买东西,首先开口的肯定是员工,比如问我们要什么东西,于是我们花钱买东西,然后把东西带走,认证过程可以类似于这样的一个过程。

- **服务端 → 客户端 **发送初始化包:服务端首先确认是那个客户端需要连接
- 客户端 → 服务端 验证
- 服务端 → 认证结果消息
- 认证通过客户端与服务端断开



![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20220318200919.png)



### 四次挥手端口tcp连接(报文段4开始)

- 第一步(客户端):TCP发送释放连接的报文,停止发送数据,释放报文首部,把FIN=1,同时发送序列号,根据上一次传送的序列号+1传送Seq = t + 1(由于下图是在连接之后立马进行四次挥手,所以序列号没有变),此时客户端进行终止等待1的状态。注意FIN不携带数据也需要消耗序列号。
- 第二步(服务端):服务器回送确认报文,发出确认报文,ACK=1,并且把回传序列号+1回传(ack = t + 1),然后再带上自己的序列号Seq = y,此时服务端进入CLOSE-WAIT状态(关闭等待状态),TCP服务器此时需要停止上层应用客户端向服务端请求释放,处于 **半关闭 **阶段,此时服务端依然可以向客户端发数据并且客户端需要接受并处理,关闭等待状态意味着整个状态还需要持续一段时间。
- 第三步(客户端):客户端接收到服务端确认请求,此时客户端进入到FIN-WAIT-2终止等待2的阶段,等待服务器的释放报文。(还有一部分服务器没有发送完的数据需要处理)
- 第四步(服务端):服务器把最后的数据处理完毕,向客户端发送释放报文,FIN=1,ack=t + 1,由于需要把剩下的数据发送完成,假设处理完成之后需要带上自己的序列号Seq=w,服务器进入**最后确认状态**,等待客户端确认。
- 第五步(客户端):客户端收到报文之后,发出确认 ACK=1,ack=w+1,自己的序列号为Seq = t + 1,此时客户端进入到了TIME-WAIT(时间等待状态),此时客户端还是没有释放,必须经过**2 * MSL(最长报文寿命)**之后,客户端撤掉TCB之后才进入CLOSED状态。
- 第六步(服务端):服务器收到客户端的请求立马进入CLOSE状态,同时撤销TCB,结束此次TCP的连接。(服务端结束TCP连接要比客户端早一些)
![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20220318200949.png)

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20220318201017.png)

> 为什么需要四次挥手才能关闭连接?
>
> ​      TCP/IP 是一种全双工的协议,任何一方关闭都需要双向的确认操作,双方关闭需要给对方发送一个FIN来终止连接,一端收到FIN通知应用层的另一端终止数据的发送,而收到一个FIN仅仅说明一个方向不进行数据流动,通常关闭的一方(发送FIN的一方)为主动关闭,接受方为被动关闭,因为全双工特性双方都需要对方被动关闭。
>

通过下面的图可以简单了解为什么要这样设计:

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20220318201146.png)

## Mysql的报文格式

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203191028391.png)



Mysql的报文格式比较简单,它主要分为下面的部分,Mysql通过自己构建的协议进行内部通信,简单了解即可:

1. 消息头:3个字节的报文长度,1个字节的序号
2. 消息体:1个字节指令,存储数据,长度不定
3. 指令案例:切换数据库(0x02),查询指令(ox03)



## 如何使用工具验证如何通信?命令是如何执行的?

连接上去之后会执行如下的操作流程。

- 客户端→服务端:发送命令包

- 服务端→客户端:发送回应包
      
      

​      命令是如何执行的?可以使用一些辅助的抓包工具查看,比如windows平台有一个wireShark的工具,我们可以通过一个简单的抓包案例查看:
​      在实际的开始之前我们需要弄清楚Mysql到底使用的是什么协议,MySQL客户端使用**TCP协议**作为底层传输协议,而使用Mysql公司自身的**Mysql Protocol协议**作为应用层协议作为内部通信。

​      这里使用window的wireShark工具抓包,读者也可以使用tcpdump进行抓包,命令行操作更加简洁:

​      首先是三次握手的过程:

​      如下面的图所示,首先由客户端发起连接请求,传送Seq序号和设置SYN为1并且设置为同步发送状态,接着服务端受到请求之后,将ACK设置为1,并且将客户端序号+1之后回送,并且也传递一个自己的序号,此时服务端也处于同步接受状态,最后当客户端受到服务端请求之后也把ack设置为1,并且传递服务端的序列号,至此建立连接。

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203182115875.png)

​      接下来是客户端和服务端的交互,由于这里使用了navicat进行连接测试,所以可以发现navicat在这其中发送了很多自己的包:

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203182147468.png)

​      这里需要注意的是在内部通信的时候Mysql使用的是自身的协议,根据客户端的命令请求返回相应的数据。

​      最后是四次挥手的过程,由于上面进行了详细的解释合理就不再啰嗦了,四次挥手的过程要复杂不少,客户端存在最终等待1和最终等待2的阶段,而服务端在接受到请求之后不会立刻回复客户端可以关闭,而是需要将数据传输完成之后,再回送客户端停止传送,当客户端收到断开指令之后,则会立即停止此次TCP交互,而客户端这里需要经过最长等待时间才会释放连接,所以对于服务器连接优化来说,TCP的最长等待时间是一个重要的优化点。

​      ![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203182202709.png)

## 数据库和excel的对比

1. 存储和磁盘空间大小类似
2. 数据库面向软件,提供接口
3. excel文件级别,面向终端用户
4. 事务:数据库千人千面



# 常见的架构

事件驱动架构

事件驱动的模式常见于GUI的软件当中,我们点击某个按钮的时候,会触发与之关联的其他事件组,从下面的架构图可以看到事件和事件执行之间是结偶的,有很好的复用性。

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203182017201.png)

管道-过滤器架构

​      管道过滤的架构比较常见是http请求过滤处理,比如我们想要对于一个请求进行不同层次的分析,对于请求次数,请求时间,或者请求来源或者对于请求拦截的处理,可以通过过滤链的方式对于请求进行处理。

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203182016823.png)

微核架构

微核架构常用于精简项目架构,通过插件的方式对于系统的核心功能增强,微核架构具有很好的灵活性,能根据不同的实际情况进行灵活组合完成不同的效果。

!(/Users/zhaoxudong/Library/Application Support/typora-user-images/image-20220318201602082.png)

分层架构

通过拆分server和存储引擎,将整个连接的步骤拆分为下面的部分,sever层负责连接管理,而存储引擎则负责与后台的交互动作。

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203182015255.png)

数据库的基础架构

在Mysql的设计中,可以看到主要使用了三种架构模式:

- 事件驱动架构
- 分层架构
- 微核架构



# 常见存储引擎介绍

1. innodb:互联网常用,支持事务。
2. myISAM:查询快。
3. memory:临时内存表。
4. Archive:归档表。



# sql语句查询过程

​      sql的查询语句大致分为下面四个模块:

- 查询缓存(8.0删除)
- 分析器
- 优化器
- 执行器
- 存储引擎



​      下面是一个SQL查询的大致步骤

1. 查询缓存(8.0删除)

2. 分析器
      - 分析语法,解析语句
      
      - 拆分编译语句
      - 解析SQL的核心步骤
      
3. 优化器
      - 通过mysql的规则优化查询链路或者sql执行的过程
      - 建立并且把执行计划传递给执行器
      
4. 执行器
      
      - 负责具体的sql执行
      - 通过存储引擎的接口进行接口调用,最后结果返回给客户端

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/202203182015792.png)

# 结语

​      前面的章节比较基础,跳过了很多内容,本部分重点是三次握手和四次挥手的过程需要多熟悉一下,另外Mysql最值得学习的是InnoDB存储引擎,如果对于数据库设计感兴趣是肯定绕不过的。

zxdsb666. 发表于 2022-3-19 12:53

aalcclcc 发表于 2022-3-19 12:09
不知道有没有详细一点的图解,看楼主这个有点复杂。

请问是那一部分呢,欢迎提意见我会及时补充

liweiqing 发表于 2022-3-18 23:58

看的我有点点蒙圈啊。。。。。。。。

justyvan 发表于 2022-3-19 06:38

学习学习

傅粉何郎 发表于 2022-3-19 08:19

又是看标题以为我会系列

goodlucksjjsky 发表于 2022-3-19 08:25

感谢分享

wshq 发表于 2022-3-19 08:47

{:1_921:}很少看到直接研究报文的,.

qwe12079 发表于 2022-3-19 08:57

很详细,谢谢

izumi49 发表于 2022-3-19 09:36

感谢楼主分享

yzmx 发表于 2022-3-19 09:47

好是好,就是好像有点难

zyxmu 发表于 2022-3-19 09:53

很好,很强大
页: [1] 2 3
查看完整版本: "三高"Mysql - Mysql的基础结构了解