一条SQL语句的完整执行过程是怎样的呢?我们用select和update语句来举例。
注意在mysql8后,进入服务层后,取消了去查询缓存(属于Server服务层)这个步骤,缓存中key是SQL语句,value是值,这样其实并不会提升性能,因为只要有修改语句,缓存数据就无效了,下面我们以mysql8为例子:
建立连接,首先经过连接层,连接器会校验你的用户名和密码是否正确,之后,会查询当前用户的权限。
进入服务层,解析器则会解析此SQL语句,进行语法分析等待,之后优化器会对sql语句进行优化,比如使用什么索引,然后就是执行器去执行SQL语句了,执行前还得判断此用户的权限。
如果是innodb引擎,先去BufferPool缓冲池(属于存储引擎)中查看是否存在对应数据,如果没有,存储引擎与磁盘进行交互,将查询结构先存入缓冲池,然后再返回。
比如 update user set name = "张三" where id = 2
前面与select语句过程一样,查出id为2的这行记录。
执行器拿到数据后,将name值改为张三。
先将这次数据修改更新到缓冲池中,同时记录内存中的redolog日志以及binlog日志,根据redolog的刷盘策略,可能也会刷新到磁盘中的redolog日志。
收到事务commit提交指令。(在此刻如果发生宕机,由于事务不是prepare状态,认为事务没有执行完毕,所以不会恢复)
刷新内存redolog到磁盘中的redolog日志,并将事务状态改为prepare,日志中记录的数据状态此刻为prepare。
将内存缓存中的binlog日志刷新到磁盘binlog日志。
刷新内存redlog到磁盘中的redolog日志,将事务状态改为commit,redolog日志中记录的数据状态为commit。
返回事务执行结果。