"三高"Mysql - Mysql的基础结构了解
引言
内容为慕课网的《高并发 高性能 高可用 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连接(报问段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是可以携带数据的,但是如果不携带数据则不消耗序列号。
- 最后一步:当服务器收到客户端的确认,也进入已连接状态。
Mysql认证连接:
(参考资料:http://mysql.taobao.org/monthly/2018/08/07/)
Mysql的认证链接可以看作是三次交互,注意第一次请求是服务端发起的,有点类似我们去店里面买东西,首先开口的肯定是员工,比如问我们要什么东西,于是我们花钱买东西,然后把东西带走,认证过程可以类似于这样的一个过程。
- 服务端 → 客户端 发送初始化包:服务端首先确认是那个客户端需要连接
- 客户端 → 服务端 验证
- 服务端 → 认证结果消息
- 认证通过客户端与服务端断开
四次挥手端口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连接要比客户端早一些)
为什么需要四次挥手才能关闭连接?
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请求过滤处理,比如我们想要对于一个请求进行不同层次的分析,对于请求次数,请求时间,或者请求来源或者对于请求拦截的处理,可以通过过滤链的方式对于请求进行处理。
微核架构
微核架构常用于精简项目架构,通过插件的方式对于系统的核心功能增强,微核架构具有很好的灵活性,能根据不同的实际情况进行灵活组合完成不同的效果。
分层架构
通过拆分server和存储引擎,将整个连接的步骤拆分为下面的部分,sever层负责连接管理,而存储引擎则负责与后台的交互动作。
数据库的基础架构
在Mysql的设计中,可以看到主要使用了三种架构模式:
- 事件驱动架构
- 分层架构
- 微核架构
常见存储引擎介绍
- innodb:互联网常用,支持事务。
- myISAM:查询快。
- memory:临时内存表。
- Archive:归档表。
sql语句查询过程
sql的查询语句大致分为下面四个模块:
- 查询缓存(8.0删除)
- 分析器
- 优化器
- 执行器
- 存储引擎
下面是一个SQL查询的大致步骤
- 查询缓存(8.0删除)
分析器
- 分析语法,解析语句
- 拆分编译语句
- 解析SQL的核心步骤
优化器
- 通过mysql的规则优化查询链路或者sql执行的过程
- 建立并且把执行计划传递给执行器
执行器
- 负责具体的sql执行
- 通过存储引擎的接口进行接口调用,最后结果返回给客户端
结语
前面的章节比较基础,跳过了很多内容,本部分重点是三次握手和四次挥手的过程需要多熟悉一下,另外Mysql最值得学习的是InnoDB存储引擎,如果对于数据库设计感兴趣是肯定绕不过的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。