MySQL逻辑架构
image image最上层的基于C/S架构模式, 即Client端.
第二层是大多数MySQL的核心服务.查询解析/分析/优化/缓存以及所有的内置函数(例如, 日期/时间/数学和加密函数等). 所有跨存储引擎的功能都在这一层实现: 存储过程 触发器 视图等.
第三层为存储引擎层. 存储引擎负责MySQL中数据的存储和提取. 存储引擎不会去解析SQL(innodb例外, 它会解析外键定义, 因为MySQL服务器本身没有实现该功能). 不同存储引擎之间不会相互通信, 而只是简单的响应上层服务器的请求. 服务器通过API与存储引擎进行通信, 这些API屏蔽了不同存储引擎之间的差异, 使得这些差异对上层的查询过程透明. 现在最常用的存储引擎是InnoDB, 从MySQL5.5.5版本成为默认存储引擎.
连接管理和安全性
每个客户端连接都会在服务器进程中拥有一个线程, 这个连接的查询只会在这个单独的线程中执行, 该线程只能轮流在某个CPU核心或者CPU中运行. 服务器会负责缓存线程, 因此不需要为每一个新建的连接创建或者销毁线程(MySQL5.5或者更新的版本提供了一个API, 支持线程池(Thread-Pooling)插件, 可以使用池中少量的线程来服务大量的连接.
连接器负责跟客户端建立连接|获取权限|维持和管理连接. 连接命令一般如下形式:
mysql -h$ip -P$port -u$user -p
通过如下语句可以查看当前连接的信息:
mysql> show processlist;
+----+------+--------------------+-------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+--------------------+-------+---------+------+----------+------------------+
| 5 | root | 192.168.33.1:57721 | mysql | Sleep | 29 | | NULL |
| 6 | root | localhost | NULL | Query | 0 | starting | show processlist |
+----+------+--------------------+-------+---------+------+----------+------------------+
2 rows in set (0.00 sec)
其中"Sleep"代表现在系统里面有一个空闲连接.
客户端如果太长时间不活动, 连接器就会自动断开. 这个是由等待超时时间wait_timeout
控制的,默认值是8小时.
数据库长连接: 指连接成功后, 如果客户端持续有请求, 则一直使用同一个连接.
数据库短连接: 指每次执行完很少的几次查询后就断开连接, 下次查询重新再建立一个.
两种连接实践方案:
- 定期断开长连接. 使用一段时间, 或者程序里面判断执行过一个占用内存的大查询后, 断开连接, 之后要查询再重连.
- 如果使用的MySQL版本是5.7或更新版本, 可以在执行一个比较大的操作后, 通过执行
mysql_reset_connection
来重新初始化连接资源. 这个过程不需要重连和重新做权限验证, 但是会将连接恢复到刚刚创建完时的状态.
查询缓存
对于SELECT
语句, 在解析查询之前, 服务器会先检查查询缓存(Query Cache
), 如果能够在其中找到对应的查询, 服务器就不用再执行查询解析--优化--执行的整个过程了, 而是直接返回查询缓存中的结果集.
极客时间<MySQL实战45讲>中: 大多数情况下不建议使用查询缓存
原因: 查询缓存的实效非常频繁, 只要有对一个表的更新, 这个表上的查询缓存都会被清空. 对于更新压力大的数据库, 查询缓存的命中率会非常低. 除非有一张静态表(很长时间才更新一次), 比如, 一个系统配置表, 那么就比较适合使用查询缓存.
MySQL提供了"按需使用"查询缓存的方式. 将参数query_cache_type
设置为DEMAND
, 这样对于默认的SQL语句都不使用查询缓存. 而对于确定要使用查询缓存的语句, 可以用SQL_CACHE
显式指定, 例如:
mysql> select SQL_CACHE * from T where ID=10;
注意: MySQL8.0版本直接查询缓存的整块功能删掉了.MySQL8.0版本功能变更介绍
分析器
- 词法分析
- 语法分析
优化器
- 选择合适的索引
- 决定各个表的连接顺序
执行器
- 判断对这个表有没有查询权限
- 有权限, 则继续执行.
- 调用存储引擎接口进行执行查询或其他操作.
- 最终将查询结果集返回给客户端, 语句即执行完成.
问题
如果表 T 中没有字段 k,而你执行了这个语句 select * from T where k=1, 那肯定是会报“不存在这个列”的错误: “Unknown column ‘k’ in ‘where clause’”。你觉得这个错误是在哪个阶段报出来的呢?
答案
分析器.
MySQL会解析查询, 并创建内部数据结构(解析树). 分析器会检查: 数据表和数据列是否存在, 别名是否有歧义等. 所以此为分析器阶段. ----- 参考自<MySQL实战45讲> 01节课后讨论@圈圈圆圆的回答.
网友评论