mysql体系结构、存储文件和sql语句的执行流程

目录

网络连接层

服务层

存储引擎层

存储引擎相关命令

系统文件层

表结构定义和数据文件

日志文件

sql执行流程

连接状态

Mysql查询高速缓冲

查询高速缓冲如何工作

不会缓存的情况

缓存参数


 

MySQL 从概念上分为四层,这四层自顶向下分别是网络连接层,服务层(核心层),存储引擎层,系统文件层。

网络连接层

主要负责连接管理、授权认证、安全等等。

服务层

第二层服务层是 MySQL 的核心,MySQL 的核心服务层都在这一层,查询解析,SQL 执行计划分析,SQL 执行计划优化,查询缓存。以及跨存储引擎的功能都在这一层实现:存储过程,触发器,视图等。

  • 连接池(Connection Pool:管理、缓冲用户的连接,线程处理等需要缓存的需求。
  • 管理服务和工具组件(Services & utilities:系统管理和控制工具,例如备份恢复、MySQL 复制、集群等。
  • SQL 接口SQL Interface:接受用户的 SQL 命令,并且返回用户需要查询的结果。
  • 查询解析器Parser:SQL 命令传递到解析器的时候会被解析器验证和解析(权限、语法结构)。
  • 查询优化器Optimizer:SQL 语句在查询之前会使用查询优化器对查询进行优化。
  • 缓存Caches:如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。

存储引擎层

  • MySQL 采用插件式的存储引擎。
  • 存储引擎是针对于表的而不是针对库的(一个库中不同表可以使用不同的存储引擎),服务器通过 API 与存储引擎进行通信,用来屏蔽不同存储引擎之间的差异。
  • 不管表采用什么样的存储引擎,都会在数据区,产生对应的一个 frm 文件(表结构定义描述文件)。

存储引擎相关命令

  1. SHOW ENGINES:查看 MySQL 支持的存储引擎。
  2. SHOW TABLE STATUS:查看当前库中的表使用的是什么存储引擎。

系统文件层

系统文件层包含数据、索引、错误日志、查询记录、慢查询日志等。

表结构定义和数据文件

在安装 MySQL 的时候会生成一个 data 目录,这个目录就是 MySQL 的数据文件路径,通过在配置文件中的 datadir 参数配置,一般情况下,不要把 MySQL 的数据文件路径配置在 MySQL 的安装目录下。

在 MySQL 的数据文件路径下,一个 Database 对应一个文件夹,每张表对应一组文件,不同存储引擎的表文件是不一样的,下面看下InnoDB和MyISAM两种存储引擎数据库对应的文件目录结构。

InnoDB的文件目录

.frm:表结构定义文件。
db.opt:记录这个库的默认使用的字符集和校验规则。

数据文件(存储表数据和索引)有两种:ibd 和 ibdata,InnoDB 存储引擎有两种表空间方式:独享表空间和共享表空间。
• 独享表空间:使用 .ibd 文件来存放数据,且每一张 InnoDB 表对应一个 .ibd 文件。
• 共享表空间:使用 .ibdata 文件,所有表共同使用一个(或多个,自行配置).ibdata 文件。

MyISAM的文件目录

.frm:表结构定义文件。
db.opt:记录这个库的默认使用的字符集和校验规。
.myd:myd文件存放 MyISAM 表的数据(data)。
.myi: 存放 MyISAM 表的索引相关信息。

日志文件

包含错误日志、慢查询日志、通用查询日志、二进制日志等。下面只看下提到的这几种文件的配置

  1. 错误日志:MySQL 错误日志记录 MySQL 运行过程中较为严重的警告和错误信息,以及 MySQL 每次启动和关闭的详细信息。默认名是:机器名.err
  2. 慢查询日志:将运行超过某个时间阈值的 SQL 语句记录到文件,默认文件名是:机器名-slow.log。
  3. 通用查询日志:可以记录数据库所有相关操作,比如客户端连接信息,执行语句的信息等,默认文件名是:机器名.log
  4. 二进制日志:MySQL 的二进制日志(binary log)是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的 MySQL 语句。二进制日志(binary log)中记录了对 MySQL 数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其它额外信息,但是它不记录 SELECT、SHOW 等那些不修改数据的 SQL 语句。二进制日志(binary log)主要用于数据库恢复和主从复制。

sql执行流程

当客户端向 MySQL 发送一个请求的时候,MySQL 的执行过程如下图所示:

image.png

连接状态

对于一个 MySQL 的连接,或者说一个线程,时刻都有一个状态来标识这个连接正在做什么。可以通过如下命令来查看连接的状态:

show full processlist   或者  show processlist

image.png

这里简单介绍几个常用的连接状态:

  1. Sleep:线程正在等待客户端发送数据。
  2. Query:连接线程正在执行查询。
  3. Locked:线程正在等待表锁的释放。
  4. Sorting result:线程正在对结果进行排序。
  5. Sending data:向请求端返回数据。

对于出现问题的连接可以通过 kill {id} 的方式进行杀掉。

Mysql查询高速缓冲

查询高速缓冲如何工作

当一个查询语句进入mysql服务器时,先去查询缓存中有没有对应的查询语句,如果没有继续向下执行,直到将结果返回,同时缓存查询语句和返回结果,如果有的话直接返回查询结果,注意下下面的两个查询被查询缓存认为是不相同的:

SELECT * FROM tbl_name 与  Select * from tbl_name 

查询必须是完全相同的(逐字节相同)才能够被认为是相同的。另外,同样的查询字符串由于其它原因可能认为是不同的。使用不同的数据库、不同的协议版本或者不同 默认字符集的查询被认为是不同的查询并且分别进行缓存。

如果一个表被更改了,那么使用那个表的所有缓冲查询将不再有效,并且从缓冲区中移出。一个表可以被许多类型的语句更改,例如INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE。

不会缓存的情况

在下面的这些条件下,查询也不会被缓存:

  1. 当查询语句中设置了 SQL_NO_CACHE,则不会被缓存。
  2. 查询语句中有一些不确定的数据时,则不会被缓存。如包含函数 NOW() ,CURRENT_DATE() 等类。
  3. 当查询的结果大于 query_cache_limit 设置的值时,结果不会被缓存。
  4. 对于 InnoDB 引擎来说,当一个语句在事务中修改了某个表,那么在这个事务提交之前,所有与这个表相关的查询都无法被缓存。
  5. 引用自定义函数(UDFs)。
  6. 引用自定义变量。
  7. 引用mysql系统数据库中的表。
  8. 查询语句不涉及到表。
  9. 下面方式中的任何一种:                                                                                                                                                                                                                                                         
    SELECT ...IN SHARE MODE/SELECT ...FOR UPDATE/

缓存参数

MySQL 的缓存参数在配置文件中设置,可以通过如下命令来查看缓存的参数:

show variables like 'query_cache%'

image.png

query_cache_type:

  • 0:不启用查询缓存,默认值
  • 1:启用查询缓存,只要符合查询缓存的要求,客户端的查询语句和记录集都可以缓存起来,供其他客户端使用,SQL 语句中加上 SQL_NO_CACHE 将不缓存
  • 2:启用查询缓存,只要查询语句中添加了参数:SQL_CACHE,且符合查询缓存的要求,客户端的查询语句和记录集,则可以缓存起来,供其他客户端使用

query_cache_size:

  • 总的缓存池的大小,允许设置 query_cache_size 的值最小为40K,默认1M,推荐设置为64M/128M
  • 当总的缓存池大小超过设置的值时,会按照时间顺序,让最老的缓存失效。

query_cache_limit:

指定单个查询能够使用的缓冲区大小。

通过query_cache_type变量开启关闭缓存。

可以在SELECT语句中指定查询缓存相关选项:SQL_CACHE/SQL_NO_CACHE

如果query_cache_type系统变量的值是ON(1)或DEMAND(2)开启了缓存(OFF/0关闭缓存),那么指定SQL_CACHE的查询结果将被缓存,指定SQL_NO_CACHE的查询结果不会缓存,如:

SELECT SQL_CACHE id, name FROM customer; -- 会缓存
SELECT SQL_NO_CACHE id, name FROM customer; -- 不会缓存

更多缓存相关的配置参考:https://www.mysqlzh.com/doc/50/208.html   

缓存的坑

1. 在查询之前必须先检查是否命中缓存,浪费计算资源。
2. 针对表进行写入或更新数据时,将对应表的所有缓存都设置失效。
3.如果这个查询可以被缓存,那么执行完成后,MySQL 发现查询缓存中没有这个查询,则会将结果存入查询缓存,这会带来额外的系统消耗。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值