java-数据库 请求响应模型如下图所示
对于MYSQL本身的架构如何呢?
MYSQL 架构
MYSQL 分为Server层,以及存储引擎层,Server 顾名思义,作为一个服务器,负责了所有的外围事情,比如连接、鉴权、SQL分析、优化等,存储引擎层完成底层的数据存储操作。
接上图,后续对MYSQL内部开展分析可能采用右侧图形样式
MYSQL的简易逻辑架构图如下:
PS:
之所以说是逻辑架构图,是因为这是系统设计呈现出来的逻辑单元,是抽象构建,物理上会有很大的不同,比如存储引擎有它自身的架构设计,逻辑抽象,但是物理上底层也都是文件、内存块。所以需要注意区分逻辑架构与物理架构实现。
下图来自于官网,一个更加准确完整的结构图,地址:
https://dev.mysql.com/doc/refman/8.0/en/images/mysql-architecture.png
图中主要分为四层:
层次 |
|
Connectors |
各种连接器,此处是指外部应用连接到MYSQL<br />不是上面我画的那个图中的连接器模块,基于tcp/ip安全连接的客户端 |
Server |
服务层,sq的接收,解析,优化,缓存等操作 |
Storage Engines |
引擎层, MySQL 中数据的存储和提取, 服务层通过 API 与存储引擎进行通信 |
File |
文件系统存储层,数据存储在物理设备上,并且与存储引擎进行交互 |
其中Server层,按照逻辑功能又可以分为下面几个部分
模块 |
功能 |
No SQL Interface |
NoSQL 部分,8.0新增的,之前没有 |
SQL Interface |
SQL接口,接受用户的SQL,然后返回给用户结果 |
Parser |
解析器,SQL命令传递到解析器,解析器验证解析 |
Optimizer |
优化器,对SQL进行优化,采取最合适的执行过程,提高性能 |
Caches&Buffers |
查询缓存 |
大致步骤:
- 客户端通过TCP/IP网络连接将select语句发送到服务端
- 服务端拿到select语句后,检查查询缓存,如果存在缓存数据,则直接返回
- 如果缓存中没有相应数据,则select语句会被Parser进行词法解析和语法解析
- 解析完成后Optimizer 将对select语句进行优化,生成执行计划
- 调用存储引擎相关接口根据执行计划做SQL查询
- 将查询结果逐层返回,最后给到客户端
Server层
包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
不同的存储引擎共用一个Server 层,类似同样一台车,通过换不同发动机,能够呈现出来不同的动力效果。
连接器
MySQL服务器提供给外部客户端的一个连接接口,客户端可以通过不同的方式进行连接,如JDBC、ODBC和原生方式API等(其本质还是建立TCP连接)。
连接层不仅是建立连接,还需要进行认证授权、维持连接等操作
这一部分主要学习如何使用,一些基本的命令,比如连接:
mysql -h$ip -P$port -u$user -p
再比如:show processlist
查看连接状态 Command
中 Sleep
表示空闲连接
Command |
含义 |
sleep |
空闲,线程正在等待客户端发数据 |
query |
连接线程正在执行查询 |
locked |
线程正在等待表锁的释放 |
sorting result |
线程正在对结果进行排序 |
sending data |
向请求端返回数据 |
SQL/NO SQL接口
接收到用户的SQL、No SQL 请求,并且返回用户需要查询的结果
这一部分主要是学习,如何编写SQL
解析器
对SQL 语句进行语法分析、语义分析。将SQL语句分解成数据结构(语法树),并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的,如果此处解释失败,说明SQL语句本身存在错误。
这一部分对于应用开发者来说可以不太关注
优化器
确定SQL语句的执行计划。
这个执行计划表明应该使用哪些索引进行查询(全表检索还是使用索引检索),表之间的连接顺序如何,最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询。
这一部分需要仔细学习分析执行计划,通过执行计划对SQL进行优化,因为自动的优化并不能让你彻底放手。
Caches & Buffers查询缓存组件
8.0之后被移除,因为其极地的命中率。
MySQL在其最新的8.0版本中,删除了查询缓存(Query Cache)区域,就此,MySQL的Query Cache彻底的退出了历史舞台。在5.7版本中,MySQL已经将Query Cache的选项(query_cache_type)的缺省值设为了关闭,并在5.7.20版本中,将该配置标记为了Deprecated。
关于这块官网有介绍:
https://dev.mysql.com/blog-archive/mysql-8-0-retiring-support-for-the-query-cache/
防止连接丢失,备份机翻地址 https://www.crazybytex.com/thread-228-1-1.html
1、查询SQL的命中
Query Cache中对SQL语句的缓存,是基于字节级别的(The query must match byte-for-byte ),这意味着SQL语句发生任何一点变化,Query Cache都无法进行命中,这对于实际生产环境的查询,显得有些过于苛刻。
2、缓存过期
Query Cache的淘汰策略过于苛刻,任何对于表中数据的修改,都会使得缓存失效,这里的修改包括:INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE,这个特性意味着,只有对于读远大于写的数据表,Query Cache才能发挥作用,对于读写均衡以及写多读少的场景,Query Cache基本上很难发挥作用。
3、分区表禁用
如果数据表使用了分区,Query Cache将会被自动的禁用,无法生效。
4、增加额外的负载
当开启Query Cache选项后,如果查询请求没有命中Query Cache时,MySQL会需要额外的性能开销去处理结果集,写入Query Cache中,最糟糕的情况下,这个额外的性能开销是13%,但实际场景中的情况会更加的复杂,通常情况下,额外的性能开销会低于该值,但这仍是一笔无谓的性能损耗。
简单说就是不划算
并且文末推荐了一个中间件缓存
存储引擎
从5.6 到5.7 再到8,存储引擎这块,抛开引擎内部的变化,MYSQL支持的存储引擎没有发生变化,且默认的都是InnoDB。
所以对于大多数的应用开发者来说,InnoDB是必须要学习的内容。
如下图所示:https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html
小结
完整的流程大致如下
转载务必注明出处:程序员潇然,疯狂的字节X,https://crazybytex.com/thread-226-1-1.html