深入剖析MySQL的基础结构:从存储引擎到数据结构

随心笔谈2年前发布 编辑
169 0
🌐 经济型:买域名、轻量云服务器、用途:游戏 网站等 《腾讯云》特点:特价机便宜 适合初学者用 点我优惠购买
🚀 拓展型:买域名、轻量云服务器、用途:游戏 网站等 《阿里云》特点:中档服务器便宜 域名备案事多 点我优惠购买
🛡️ 稳定型:买域名、轻量云服务器、用途:游戏 网站等 《西部数码》 特点:比上两家略贵但是稳定性超好事也少 点我优惠购买

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

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

tcp/ip的连接形式
共享内存的连接方式

命名空间模式

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连接
第一步:客户端主动打开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是可以携带数据的,但是如果不携带数据则不消耗序列号。

最后一步:当服务器收到客户端的确认,也进入已连接状态。

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

服务端 → 客户端 发送初始化包:服务端首先确认是那个客户端需要连接

客户端 → 服务端 验证

服务端 → 认证结果消息

认证通过客户端与服务端断开

四次挥手端口tcp连接
第一步(客户端):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连接要比客户端早一些)

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

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

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

消息头:3个字节的报文长度,1个字节的序号

消息体:1个字节指令,存储数据,长度不定

指令案例:切换数据库(0x02),查询指令(ox03)

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

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

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

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

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

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

首先是三次握手的过程:

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

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

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

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

数据库和excel的对比
存储和磁盘空间大小类似

数据库面向软件,提供接口

excel文件级别,面向终端用户

事务:数据库千人千面

常见的架构

事件驱动架构

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

管道-过滤器架构

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

微核架构

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

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

分层架构

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

数据库的基础架构

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

事件驱动架构

分层架构

微核架构

常见存储引擎介绍
innodb:互联网常用,支持事务。

myISAM:查询快。

memory:临时内存表。

Archive:归档表。

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

查询缓存(8.0删除)

分析器

优化器

执行器

存储引擎

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

查询缓存(8.0删除)

分析器

分析语法,解析语句

拆分编译语句

解析SQL的核心步骤

优化器

通过mysql的规则优化查询链路或者sql执行的过程

建立并且把执行计划传递给执行器

执行器

– 负责具体的sql执行- 通过存储引擎的接口进行接口调用,最后结果返回给客户端

© 版权声明

相关文章