本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、前言
作为一个合格的程序员,特别是后端程序员,都要求我们至少要掌握一门数据库技术,而在众多数据库中,MySQL的人气一直居高不下,在企业中的应用也是非常广泛,相信大部分人对它都不陌生。
要掌握一门数据库技术,除了要了解其基本用法以外,还需要了解其内部流程,而在本篇文章中,则会从一个更新SQL的请求出发,带大家了解MySQL的整体更新流程。
二、MySQL整体更新流程
MySQL的更新流程如下图:
1、MySQL客户端
MySQL的更新SQL请求,一般都是通过MySQL客户端发起的,它的主要作用是封装与MySQL交互过程,是用户可以方便的通过其GUI界面或者API操作MySQL数据库。
常见的MySQL的GUI客户端有Navicat、Bearer等,除此之外,还有一些API包,可以供各种编程语言引用,以实现数据库操作,例如Java常用的mysql-connector-java-*.jar。
在MySQL客户端与MySQL数据库完成登录后,会创建一个数据库连接池,用来管理与MyS到L数据库的连接。
为什么需要数据库连接池?
MySQL客户端每次与MySQL数据库建立连接,都需要经过TCP/IP的三次握手,系统上的开销是较大。为了实现连接的复用,防止频繁的创建连接,于是就有人创建了数据库连接池,用来进行连接管理。目前比较常用的数据库连接池是阿里的Druid。
用户在MySQL客户端发起请求后,客户端会从数据库连接池获取到一个数据库连接,然后将请求的SQL通过数据库链接发送给MySQL数据库。
2、MySQL数据库
在MySQL数据库中,主要可以分为网络连接层、系统服务层和存储引擎层。
2.1、网络连接层
MySQL的网络连接层的主要作用是对接MySQL客户端,在MySQL客户端发送连接请求的时候进行用户校验以及管理MySQL数据库的连接。
在MySQL客户端与MySQL数据库建立连接后,网络连接层会为每个数据库连接绑定一个工作线程,并将这个数据库连接放入到数据库连接池中。
为什么MySQL客户端和MySQL数据库各有一个连接池?
MySQL客户端的连接池主要是用来维护数据库连接,实现数据库连接复用;MySQL数据库的连接池主要是用来维护工作线程的。
回归本文,在MySQL客户端通过数据库连接向MySQL数据库发送一个更新SQL请求后,网络连接层会将这个SQL发送到当前数据库连接绑定的工作线程中,以进行后续处理。
2.2、系统服务层
SQL接口
工作线程在收到更新SQL后,会将SQL传给通过SQL接口传给缓存组件。
SQL接口的主要作用是接收SQL,并在SQL执行结束后,将结果返回给上一层。
缓存
缓存组件在收到SQL后,会根据SQL计算出一个hash值,再根据hash值去查询缓存。若缓存存在,则删除缓存;若不存在,则将SQL发给解析器。
缓存组件的主要作用是用来提高查询性能,在执行查询SQL时,若缓存中有数据,则直接返回缓存,不再进行后续处理。但是由于查询缓存命中率不高,所以在MySQL8以后,MySQL去除了缓存组件。
解析器
解析器收到SQL后,会对SQL进行解析,对其进行词法分析、语义分析等,校验SQL的合法性,并最终生成一个解析树,然后将其发给优化器。
优化器
优化器的主要作用是根据解析器传过来的解析树生成一个MySQL数据库认为的最优的执行计划。在这过程中,优化器会选择最合适的索引、最合适的join方式等。最终,工作线程会根据执行计划,调用存储引擎的接口,去进行数据操作。
2.3、存储引擎层
MySQL的存储引擎层作为MySQL数据库的核心,跟Oracle、SQL server等数据库不一样,它是插件式的,可以类似插件的方式,集成各种不同的存储引擎。目前比较常用的MySQL数据库引擎有InnoDB、MyIsam、Memory等,用户可以根据表的不同用处,选择最合适的存储引擎。
回归本文,存储引擎在收到MySQL系统服务层的请求后,会按照接口请求进行数据处理,并将处理结果返回给系统服务层,最后将数据持久化到硬件上。
2.3、硬件层
除了个别存储引擎以外,大部分存储引擎数据处理完以后,最终还是要将数据保存到硬件上。
存储到硬件上的文件,除了表数据以外,还包括数据库操作过程中产生的日志,例如:binlog、redolog、undolog等。