二、MySQL整体结构浅析
本章作为MySQL
系列的开篇之作,当然也有一定的原因,毕竟只有先对MySQL
的整体架构有了一个宏观的认知,才能更好的理解每个细节点的知识。
MySQL
与我们开发项目时相同,为了能够合理的规划整体架构设计,也会将整个MySQL
服务抽象成几个大的模块,然后在内部进行实现,因此先来看看MySQL
的整体架构,开局先上一张图:
从上往下看,依次会分为网络连接层、系统服务层、存储引擎层、以及文件系统层,往往编写SQL
后,都会遵守着MySQL
的这个架构往下走。
- 连接层:主要是指数据库连接池,会负责处理所有客户端接入的工作。
- 服务层:主要包含
SQL
接口、解析器、优化器以及缓存缓冲区四块区域。 - 存储引擎层:这里是指
MySQL
支持的各大存储引擎,如InnoDB、MyISAM
等。 - 文件系统层:涵盖了所有的日志,以及数据、索引文件,位于系统硬盘上。
OK~,除了上述的四层外,还有客户端,这个客户端可以是各类编程语言,如Java、Go、Python、C/C++、PHP、Node、.Net....
,也可以是一些数据库的可视化软件,例如Navicat、SQLyog
等,也可以是mysql-cli
命令行工具。总之,只要能与MySQL
建立网络连接,都可以被称为是MySQL
的客户端。
MySQL-Server
就是上述图中的那玩意儿,一般来说,客户端负责编写SQL
,而服务端则负责SQL
的执行与数据的存储。
对MySQL
的整体架构有了简单了解后,接下来详细的拆解一下MySQL-Server
的每个层面。
三、网络连接层
当一个客户端尝试与MySQL
建立连接时,MySQL
内部都会派发一条线程负责处理该客户端接下来的所有工作。而数据库的连接层负责的就是所有客户端的接入工作,MySQL
的连接一般都是基于TCP/IP
协议建立网络连接,因此凡是可以支持TCP/IP
的语言,几乎都能与MySQL
建立连接。
其实
MySQL
还支持另一种连接方式,就是Unix
系统下的Socket
直连,但这种方式一般使用的较少。
虽然MySQL
是基于TCP/IP
协议栈实现的连接建立工作,但并非使用HTTP
协议建立连接的,一般建立连接的具体协议,都会根据不同的客户端实现,如jdbc、odbc...
这类的。在这里先暂且不纠结连接MySQL
时的协议类型,先来看看一般是怎么连接MySQL
的?如下:
mysql -h 127.0.0.1 -uroot -p123456
例如上述这条指令,-h
表示MySQL
所在的服务器IP
地址,-u
表示本次连接所使用的用户名,-p
则代表着当前用户的账号密码,当执行这条指令后,会与MySQL-Server
建立网络连接。当然,MySQL
也支持SSL
加密连接,如果采用这种方式建立连接,那还会经过[《SSL多次握手过程》,当握手结束,网络建立成功后,则会开始正式的数据库连接建立工作。
TCP
网络连接建立成功后,MySQL
服务端与客户端之间会建立一个session
会话,紧接着会对登录的用户名和密码进行效验,MySQL
首先会查询自身的用户表信息,判断输入的用户名是否存在,如果存在则会判断输入的密码是否正确,如若密码错误或用户名不存在就会返回1045
的错误码,如下信息:
ERROR 1045 (28000): Access denied for user 'zhuzi'@'localhost' (using password: YES)
如果你在连接数据库的过程中,出现了上述的错误信息,那绝对是你输入的用户名或密码错误导致的,当账号及密码正确时,此时就会进入MySQL
的命令行,接下来可以执行SQL
操作。
但实际上,在用户名和密码都正确的情况下,
MySQL
还会做一些些小动作,也就是会进行授权操作,查询每个用户所拥有的权限,并对其授权,后续SQL
执行时,都会先判断是否具备执行相应SQL
语句的权限,然后再执行。
OK~,经过上述流程后数据库连接就建立成功了,数据库连接建立成功后,MySQL
与客户端之间会采用半全工的通讯机制工作,与之对应的还有“双全工、单工”的工作模式:
- 双全工:代表通讯的双方在同一时间内,即可以发送数据,也可以接收数据。
- 半全工:代表同一时刻内,单方要么只能发送数据,要么只能接受数据。
- 单工&#