mysql的基本架构图
server层:连接器,查询缓存,分析器,优化器,执行器等,涵盖mysql的大多数核心服务功能,以及所有的内置函数(如日期,时间,数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程,触发器,视图等
存储引擎层:负责数据的存储和提取,插件式架构模式
一条SQL语句的执行过程
查询语句
- 客户端发送一条查询给服务器
- 服务器先查询缓存(若有必要的话),如果命中了缓存,则立刻返回存储在缓存的结果,否则进入下一阶段
- 分析器进行sql解析,预处理,再由优化器生成对应的执行计划
- 执行器校验客户端是否有表的操作权限,没有就拒绝,有则mysql根据优化器生成的执行计划,调用存储引擎的api来执行查询
- 将结果返回给客户端
更新语句
- 执行器先找存储引擎找到要更新的这条数据,若该数据所在的数据页本来就在内存中,就返回给执行器,否则需要先从磁盘中读入内存再返回
- 执行器拿到该行数据,更新,再掉入存储引擎接口再写入这行新数据
- InnoDB引擎把数据保存在内存中,同时记录redo log,此时redo log进入prepare状态,然后告诉执行器,执行完成了,随时可以提交
- 执行器收到通知后记录binlog,然后调用引擎接口,将redo log改为commit
- 更新完成
连接器
负责跟客户端建立连接,获取权限,维持和管理连接
- 认证身份,即校验用户名和密码
- 校验权限:连接成功后的权限修改只会在下次重新连接时才会生效
- 连接成功后默认维持时间为8h:即若客户端连续8h没有新的请求,连接器会自动断来连接,时间可由wait_timeout配置
长连接:连接成功后,若客户端持续有请求,则一直使用同一个连接;短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个
- 使用长连接会增加mysql占用的内存,因为mysql在执行过程中临时使用的内存是管理在连接对象里的,这些资源会在连接断开时才释放,所以如果长连接累计可能会导致内存占用太大,被系统强行杀掉(OOM),从现象上看就是mysql异常重启了
-
- 定期断开长连接
- mysql5.7级以上版本,可以通过mysql_reset_connection重新初始化连接资源,该过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态
查询缓存
Mysql 8.0级以上的版本都去掉该功能了
- 缓存失效:只要有对一个表的更新,这个表上所有的查询缓存都会被清空
- 按需使用:设置参数query_cache_type为DEMAND,这样默认的sql语句都不会使用查询缓存,需要查询缓存的用 SQL_CACHE显示指定
- 推荐在读多写少的表中使用
分析器
- 词法分析
- 语法分析:校验是否满足mysql语法
优化器
- 在有多个索引时,决定使用哪个索引
- 在一个语句有多表join时,决定各个表的连接顺序
执行器
- 校验对该表有没有具体执行的权限
- 调用innodb引擎接口取表的每一行数据,check是否符合要求,是则返回,不是则下一条
日志模块
redolog
Innodb存储引擎实现的,物理日志,记录“在某个数据页做了什么修改”
目的:实现crash-safe,即使数据库发生异常重启,之前提交的记录都不会丢失
原因:保证持久必须将数据记录到磁盘中,但是每次写入磁盘都需要找到对应的那条记录再更新,成本很高,但是redolog时顺序写入的,不需要寻址,效率较高
机制:当有一条记录需要更新时,InnoDB引擎会先把记录写到redolog里,并更新内存,此时更新操作就算完成了,InnoDB引擎会在适当的时候,将这个操作记录更新到磁盘里
redolog是固定大小的,从头开始写,写到末尾就又回到开头循环写,如图:
- write ops 是当前记录的位置,当写入新数据时,write ops会往后移
- checkpoint是可用空间的终点,当前要擦除的位置,也是往后推移并循环的,擦除记录前要把记录更新到数据文件
- write ops和checkpoint之间是空着的部分,用来记录新的操作;如果writeops 追上了checkpoint就不能再执行新的更新了,需要停下来将redolog的内容记录到数据文件里
binlog
Server层的日志,用于归档
- 逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的C字段加1”
- 追加写,binlog文件写到一定大小后切换到下一个,不会覆盖以前的日志
两阶段提交日志
prepare阶段的redolog即可以提交事务,也可以回滚事务,取决于能否在binlog中找到当前事务,若能找到就提交,找不到就回滚
WAL技术
redolog就是WAL技术的应用
Write-Ahead Logging,先写日志,再写磁盘,这里的日志也是持久化到磁盘的,只是日志是顺序写盘,速度很快,而写磁盘是随机写入