1.连接器
通过连接器与客户端建立建立连接、获取权限、维持及管理连接。
mysql -h$ip -P$port -u$user -p
- 校验用户名及密码
- 校验通过后,在权限表中查询该用户的权限
SHOW PROCESSLIST;
显示连接器与客户端的连接信息,当连接闲置时,Command 值为 Sleep(休眠或空闲(sleep),查询(query),连接(connect)),如果客户端超过 8 小时没有动作,连接器会将连接关闭(wait_timeout 默认为 8 小时)
在与客户端建立连接的时候,一般都会采用长连接,频繁的短连接会对性能有影响。MySQL 执行时使用的内存保存连接对象中,直到连接断开才会释放,因此长时间的长连接可能会导致内存占用过大,出现 OOM 的情况(MySQL异常重启)
解决方法:
- 定期或者在执行一个占用内存大的 SQL 操作后,断开长连接
- 在执行一个占用内存大的 SQL 操作用,执行 mysql_reset_connection 初始化连接资源
2.缓存查询
MySQL 接收到查询请求后,会先去查询缓存查询进行查询(key-value 形式,查询语句为 key,查询结果的 value),如果匹配上 key,会将 value 直接返回,不匹配则进行下一步
(MySQL 8.0 版本后缓存查询功能移除)
3.分析器
- 词法分析:识别 SQL 语句
- 语法分析:判断是否符合 MySQL语法
4.优化器
优化 SQL 语句的执行效率,在多种执行方案中选择进行选择
5.执行器
根据优化器的执行方案执行语句
- 判断对该表的执行权限
- 有权限,则打开表继续执行
执行的时候会根据该表的引擎定义,使用这个引擎体提供的接口
上述为查询语句的执行过程,更新语句与上面类似,不过在这个表更新的时候,该表的查询结果会被清空,然后更新语句涉及到 redo log(重做日志,Server 层,InnoDB 独有) 和 binlog(归档日志,引擎层,所有引擎都有)
当更新一条记录时,InnoDB 会先将记录写入redo log,并更新内存(这时就算完成 update操作),然后在系统空闲的时候写入磁盘。即使数据库发生异常重启,之前提交的记录也不会丢失(crash-safe)。
图源于极客时间 《MySQL 45讲》
redo log 与 binlog 区别:
- redo log 是 InnoDB 独有的,空间大小固定,写入数据时循环写; binlog 是所有引擎都有的,写入日志时可以追加写入(一个写 binlog 写到一定大小会新起一个 binlog)
- redo log 是物理日志,binlog 是逻辑日志,记录对应的 SQL 语句
- redo log 是在事务进行的时候持续写入,binlog 是在事务提交后一次写入