MySQL执行背后隐藏了什么?

MySQL的基本体系和架构介绍
相信在大部分的程序员在工做中都有接触过MySQL这款数据库,在MySQL的官网上边,你会看到这样的一段介绍内容:mysql

MySQL执行背后隐藏了什么?

大体翻译过来的意思就是说:git

MySQL是世界上最受欢迎的开源数据库。不管您是快速增加的Web资产,技术ISV仍是大型企业,MySQL都能经济高效地帮助您交付高性能,可扩展的数据库应用程序。程序员

这款开源的数据库,其源码在github上边的地址为:https://github.com/mysql/mysql-server star仍是挺多的。github

那么既然是一款公认好用的开源数据库,咱们是否应该对它进行一个深刻的了解呢?算法

下边我画了一个大体的MySQL基本架构图:sql

MySQL执行背后隐藏了什么?
客户端
MySQL的总体结构能够分红2个大模块,分别是客户端和服务端。这里头说的客户端是指提供链接MySQL的工具集合,常见的客户端工具备mysql client,mysqladmin,mysqldump,mysqlcheck,mysqlimport,mysqlshow等等。数据库

MySQL数据库自己提供的链接方式包含有多种,其中最多见的就是基于TCP/IP协议进行链接了。基础的命令内容为:缓存

mysql -h [地址] -u [用户名] -p [密码]

在安装完毕了MySQL数据库以后,咱们会发现数据库自身已经帮咱们预先设置了一个名字叫作mysql的数据库,每次获取连接的时候就会到该库里面的User表检索帐号信息以及相关的权限。服务器

在Linux系统中,有不少进程间通讯方式,套接字(Socket)就是其中的一种。但传统的套接字的用法都是基于TCP/IP协议栈的,须要指定IP地址。若是不一样主机上的两个进程进行通讯,固然这样作没什么问题。可是,若是只须要在一台机器上的两个不一样进程间通讯,还要用到IP地址就有点大材小用了。markdown

MySQL数据库自身是支持UNIX域套接字进行通讯的,所以在MySQL的文件目录下边会有这么一份文件:mysql.sock。

这份文件主要是经过Unix域套接字供咱们将本地链接数据库服务器使用。

之前笔者就遇到过sock文件被修改,致使链接数据库异常的状况,例如mysql的log中出现这种报错记录:

Could not create unix socket lock file

若是sock文件丢失的话,能够从新建立一份sock文件进行通讯。

MySQL的连接分析

关于mysql的连接部分,能够先思考一下下边的这个问题:

MySQL的连接分类包含有哪些?

其实MySQL的连接包含有不少种类型,常见的类型有:

  • Unix Sockets

  • TCP/IP

  • TLE/SSL

在MySQL的连接中,主要的分类有长连接类型和短链接类型。

短链接

每次客户端和服务端进行通讯的时候,都须要建立连接—>进行通讯—>关闭链接。这种连接的咱们将其定义为短链接,从它的操做来看这种链接的行为对于资源的浪费和网络的消耗是最高的。因此一般咱们在工做中较少使用。

长连接

长连接是咱们工做中比较经常使用的类型,客户端第一次构建链接以后就不会轻易断开,这样能够给后边屡次链接的程序应用所使用,这种设计的好处在于可以减小资源的损耗,相对于短链接来讲要高效些。

长连接一般都会被设计存储在链接池里面,从而减小链接建立的开销。若是在工做中遇到了一些并发请求比较高的业务场景,光是单单经过配置链接池的方式仍是不够的,还须要有经验的开发人员在业务层进行相应的隔离。

对于一些访问量比较低的应用其实能够不使用到链接池这种较重的组件,有可能大量的长连接创建了以后都处于sleep状态,这样对于内存资源的占用会比较高。

服务端
每次客户端想要连接到服务端都须要从服务端的链接池获取相应的链接。假设咱们每次链接都须要完成 构建连接,当咱们获取到了连接以后,在mysql的server端能够经过这样一个命令来对每一个连接的状态进行查看:

mysql> show processList;

结果:

+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+

| Id | User        | Host      | db   | Command | Time   | State                                                  | Info             |
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
|  2 | system user |           | NULL | Connect | 195290 | Waiting for master to send event                       | NULL             |
|  3 | system user |           | NULL | Connect |    257 | Slave has read all relay log; waiting for more updates | NULL             |
| 19 | root        | localhost | NULL | Query   |      0 | starting                                               | show processList |
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
3 rows in set (0.01 sec)

除了上边的这种状况以外,若是当链接数较多的时候,但愿可以清晰查看到链接的信息能够经过下边这条指令来操做:

show status like 'Threads%';

结果内容:

+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 213   |  当前被缓存的空闲线程的数量
| Threads_connected | 191    | 正在使用(处于链接状态)的线程
| Threads_created   | 409   |  服务启动以来,建立了多少个线程
| Threads_running   | 5     |  正在忙的线程(正在查询数据,传输数据等等操做)
+-------------------+-------+

查询缓存

对于一些数据修改变更比较少的表,MySQL内部提供了一套叫作Query Cache的缓存池来进行存储。MySQL能够经过如下命令来查看内部的查询缓存参数值:

mysql> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| have_query_cache             | YES     |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 1048576 |
| query_cache_type             | OFF     |
| query_cache_wlock_invalidate | OFF     |
+------------------------------+---------+
6 rows in set (0.00 sec)

关于查询缓存的功能,在MySQL中是根据sql语句来作缓存检索的,默认状况下该缓存属性是关闭的,对于更新频率较高的表而言,设置查询缓存其实自己的命中率并不高,所以该功能MySQL也并不提倡使用,在MySQL8.0的时候该功能也被移除了。

MySQL服务器团队有一篇关于此的详细文章有所说起到移除的缘由,具体地址以下:
https://mysqlserverteam.com/mysql-8-0-retiring-support-for-the-query-cache/

语法分析器

接下来即是语法分析环节了,该模块主要是对传入的SQL语句内容作一些语法内容的校验,例如判断该语句是属于DQL仍是DML等类型。

其实我我的以为MySQL里面最为复杂的部分就是SQL的语法树生产的部分,对于这部分的生成须要对编译器的原理有必定的了解,我我的的功力不是很足,因此这里借用了美团一朋友以前分享给个人图片来大概演示:

MySQL执行背后隐藏了什么?
优化器

有时候你会发现,执行的一条SQL可能并不会按照预期的方式来走索引,这是由于MySQL内部有优化器这么一个角色的存在。固然索引的选择只是优化器的其中一项特色,优化器的目的就是经过必定的逻辑判断,将sql执行的效率发挥到最高效化。

执行器

当Sql准备好了,优化结束了,执行器便会发起sql请求引擎层的接口,这个环节中,执行器还会去判断当前请求的会话是否有权限执行相关的SQL语句。

存储引擎

能够说整个数据库的核心部分就是存储引擎环节了,不一样的存储引擎对数据的存储结构和算法设计方便都有着巨大的差异,并且不一样的存储引擎专门为不一样的应用场景所设计。

目前咱们主流的存储引擎有Innodb,MyISAM,Memory等

经过下边的这条命令咱们能够看到MySQL数据库所支持的存储引擎有哪些:

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)

关于MySQL的总体架构介绍大概到这里就先暂时告一段落了,下一篇文章我会讲解一些关于存储引擎的比对问题。

相关文章
相关标签/搜索