一、SQL执行前
(一)连接池
1、客户端数据库连接池
(1)代表:Druid、Hikari等;
(2)用于维护数据库连接(网络连接);
2、Mysql数据库连接池
(1)属于Mysql的成员;
(2)用于维护数据库工作线程;
(二)准备工作
1、验证客户端的用户名和密码
如果用户名不存在或密码错误,则抛出1045的错误码及错误信息;
2、判断MySQL连接池中是否存在空闲线程
(1)存在:直接从连接池中分配一条空闲线程维护当前客户端的连接;
(2)不存在:创建一条新的工作线程;
3、用户权限验证
工作线程查询MySQL的用户权限表,获取当前登录用户的权限信息并授权;
二、SQL语句的执行
(一)查询语句
1、类型
select
2、流程(由工作线程贯穿执行)
(1)SQL接口:根据hash值查询缓存,缓存未命中交给解析器;聚合存储引擎返回的数据;
(2)解析器:词法分析、语法分析、生成语法树;
(3)优化器:生成多个执行计划,选出最优执行计划,根据执行计划调用存储引擎API;
(4)存储引擎:根据上方调用执行相应操作,从磁盘检索数据,逐条返回给SQL接口;
(5)磁盘文件:与存储引擎交互,提供数据支持;
(二)写入语句
1、类型
insert、update、delete
2、流程(由工作线程贯穿执行)
(1)SQL接口:清除缓存;
(2)解析器:词法分析、语法分析、生成语法树;
(3)优化器:生成多个执行计划,选出最优执行计划,根据执行计划调用存储引擎API;
(4)缓冲区:判断是否存在操作的表数据和行数据,存在则直接在缓冲区写入数据,Checkpoint机制刷写到磁盘;
(5)存储引擎:根据上方调用执行相应操作,触发磁盘IO写入数据;
(6)磁盘文件:与存储引擎交互,提供数据支持;
(7)bin-log日志:记录日志,redo-log日志改为commit状态,返回提交成功给SQL接口;
(8)唯一性判断:如果表中的某个字段建立了唯一约束或唯一索引,当插入/修改一条数据时,会先检测目前插入/修改的值是否与表中的唯一字段存在冲突;
3、写操作的日志
(1)undo-log(执行计划执行前记录):所有的写SQL在执行之前都会生成对应的撤销SQL,用于回滚;
(2)redo-log(执行计划执行前记录):如果服务器或者MySQL宕机,重启时就可以通过redo_log日志恢复更新的数据(prepare -> commit);
(3)bin-log(执行计划执行完成后记录):记录对数据库发生更改的SQL,是MySQL自带的日志;
(4)日志记录先写到缓冲区中,然后再异步刷写到磁盘中;
三、SQL执行后的返回
(一)读操作的返回
1、流程
(1)从磁盘检索的数据逐条返回给SQL接口;
(2)SQL接口进行数据再处理,筛选出需要的数据列,返回给客户端;
2、注意点
(1)在磁盘中检索数据时,会将整条行数据全部查询出来;
(2)多表联查时,数据的合并工作也是在SQL接口完成;
(3)如果没有查询到数据,也会将执行状态、执行耗时这些信息返回给SQL接口,然后由SQL接口向客户端返回NULL;
(二)写操作的返回
1、流程
执行完成后SQL接口直接返回结果给客户端;
2、注意点
(1)仅会返回执行状态、受影响的行数以及执行耗时;
(2)如果执行成功,受影响行数一般都会大于0,反之则会等于0;