整体结构
整体结构可以分为四部分,从上往下看(MySQL语句执行顺序),依次是网络连接层、系统服务层、存储引擎层、文件系统层。
- 网络连接层: 主要是数据库连接池,会负责所有客户端接入的工作
- 系统服务层:主要包含SQL接口、解析器、优化器、缓存缓冲区
- 存储引擎层:MySQL各大引擎,常用的InnoDB和MyISAM
- 文件系统层:涵盖了所有的日志、数据、索引文件,位于系统硬盘上
客户端负责编写SQL,服务器负责SQL的执行与数据的存储
网络连接层
网络连接层的流程:当一个客户端尝试与MySQL连接时,MySQL内部会分派一条线程负责处理客户端的后续工作。数据库的连接层负责所有客户端的接入工作。 MySQL的连接方式:基于TCP/IP协议建立连接;socket直接连接
连接代码mysql -h 127.0.0.1 -u 用户名 -p 密码
当执行该代码时,会经历TCP的三次握手
,同时也支持SSL加密连接
。建立连接后,mysql服务端会与客户端建立一个session会话
,接着会对客户端登录的用户名和密码进行校验。首先查询自身的用户名信息,判断输入的用户名是否存在,存在的话再判断密码,如密码错误或用户名不存在,则返回1045错误
。
实际上,在用户名和密码都正确时,mysql会进行授权操作,查询每个用户的权限,并对其授权,后续sql执行时,会先进行判断是否有执行相应sql的权限。
到这里数据库连接就建立成功了,成功后,Mysql与客户端之间采用半双工
的通讯机制。
- 全双工:代表通讯的双方在统一时间内,既可以发送数据,也可以接收数据
- 半双工:同一时刻,单方只能发送数据或者接收数据
- 单工:只能发送或者接收数据
系统服务层
系统服务层包括SQL接口、解析器、优化器、缓存
SQL接口
该接口主要作用:负责处理客户端的SQL语句。当收到SQL语句时,SQL接口将其分给其他组件,然后等待接收执行结果的返回,最后将其返回给客户端
存储过程:预先写好并编译完成的SQL。
触发器与存储过程的不同点:存储过程需要手动调用才执行;触发器可由某个事件主动触发执行
解析器
客户端连接发送的SQL语句,经过SQL接口后会被分发到解析器。 解析器负责词法分析、语义分析、语法树生成,作用:为了验证SQL语句是否正确,以及将SQL语句解析成MySQL能看懂的机器码指令。一旦检测到mysql语句错误,会报错1064错误码
优化器
优化器:负责生成执行计划,例如选择最合适的所i你,选择最合适的join方式,最终选择出一套最有的执行计划。
执行器是不存在的,每个客户端连接在mysql中都用一条线程维护,线程是操作系统最小执行单位,执行器=线程。
缓冲&缓存
引入缓存的目的:为了通过内存的速度弥补磁盘速度对数据库造成的影响,缓冲区可以减少大量的磁盘IO,提高数据库性能。
分为读取缓存、写入缓冲。
读取缓存:select语句的数据缓存、权限缓存、引擎缓
存等。mysql对一些经常执行的查询sql语句,将其结果保存在Cache中,下次如果再出现相同的sql语句,直接从内存缓存中命中数据,比读取磁盘高效。但是在高版本的mysql中,移除了查询缓存区,命中率不高,并且带来额外开销。一般程序使用redis做一次缓存。
写入缓冲:先从缓冲区查询是否有自己想要操作的页,有的话,则直接对内存中的数据页进行操作,操作完成后,直接给客户端返回成功的信息,然后mysql会在后台利用一种叫checkpoint
的机制,将内存中更新的数据刷写到磁盘。
存储引擎层
存储引擎:InnoDB、MyISAM等
文件系统层
这一层是mysql的基础,基于机器物理磁盘的一个文件系统,包括:配置文件、库表结构文件、数据文件、索引文件、日志文件等。 主要板块:日志板块、数据板块
日志模块
七种常用的日志类型
binlog
:二进制日志,主要记录mysql数据库的所有写操作(增删改)redo-log
: 重做/重写日志,mysql崩溃时,对于未写进磁盘的操作会记录在里面,用于重启时重新写入(InnoDB专有)undo-logs
:撤销/回滚日志:记录事务开始前[修改数据]的备份,用于回滚事务error-log
:错误日志general-log
:常规日志:mysql收到的每一个查询或sql命令slow-log
:慢查询日志,记录执行时间较长的sqlrelay-log
:中继日志,用于主从复制做数据拷贝
数据模块
不同的数据在磁盘空间中,存储的格式也不相同,这是由存储引擎不同导致的。
db.opt文件
:记录当前数据库所使用的字符集和验证规则等信息.frm文件
:存储表结构的元数据信息文件,每张表都有该文件.MYD文件
:存储表中所有数据的文件(MyISAM独有).MYI文件
:存储表中索引信息的文件(MyISAM独有).ibd文件
:存储表数据和索引信息的文件(InnoDB独有) 从上面可以看出MyISAM引擎和InnoDB的一点不同:MyISAM数据和索引是分开存储,而InnoDB是数据和索引在一个文件进行存储