一、SQL执行流程
SQL的执行流程首先会分为三层,包括连接层、服务层、存储引擎层。
在连接层中使用mysql执行sql语句必须先要使用TCP/IP通信协议通过MYSQL的连接层校验账号密码和权限建立数据库连接,这里的连接方式是长连接。
在服务层中需要通过==解析器==来进行词法、语法的分析。再通过==优化器==根据解析器得到的解析树生成不同的执行计划,然后选择一种最优的执行计划。最后通过==执行器==利用存储引擎提供的相关API来完成操作,并且把数据返回给我们客户端。
在存储引擎层需要处理的逻辑。例如:
- update user set name=”xxx” where id = 1;
- 假如存储当前SQL的数据页并没有Buffer Pool,我们需要通过磁盘读取一个包含当前数据页的page页,加载到Buffer Pool缓冲区中。
- 我们把id=1数据写入undo log,用于数据回滚。
- 将id=1的行上的name列值改为xxx。
- 将结果更新到内存中。
- 记录redo log,并将这行记录状态设置为prepare。
- 修改好了就可以提交事务了。
- 先写入bin log。
- commit提交事务。
- 将redo log里这个事务的相关记录状态设置为commit状态。
- 返回结果集。
二、Mysql中的三大日志
- redo log:还没来得及同步、丢失的数据会存到这个日志文件中,保证了内存数据的安全性,延迟刷盘,进而提升系统的吞吐,为innoDB提供了崩溃恢复的特性,实现持久性,redo log记录的是在某个数据页上做了什么修改,属于物理日志。redo log的大小是固定的,前面的内容会被覆盖,一旦写满,就会触发buffer pool到磁盘同步,以便腾出空间记录后面的修改。
- undo log:记录事务发生之前的数据状态,发生异常回滚,保证原子性。
- bin log:以事件的形式记录了所有DDL和DML语句,(记录的是操作而不是数据值,属于逻辑日志)可以用来做主从复制和数据恢复。
三、undo log具体怎么回滚事务
对于insert类型的sql,undolog中会记录你insert进来的数据ID,当你想rollback时,根据ID完成删除。 对于delete类型的sql,undolog中会记录你删除的数据,当你回滚时会将删除前的数据insert。 对于update类型的sql,undolog会记录下修改前的数据,回滚时只需要反向update。
四、Buffer Pool是怎么做到降低读写磁盘IO次数
读:有一个重要的概念,page默认大小16k,Buffer Pool操作数据的最小单元,在操作系统和存储引擎中,都有预读的概念,当磁盘上一块数据被读取的时候,其他附近的数据也会马上被读取,这个叫做局部性原理
写:当我们Buffer Pool中的一个page页被更改了,那么这个数据页就是我们的脏数据页,脏数据页就是和我们的磁盘数据不一致,为了保证一致,我们就需要把脏数据页刷写到磁盘,这个动作叫做刷脏
五、刷脏模式
- 空闲模式:系统空闲就刷
- 脏页自适应:根据脏页产生的速度来刷
- Redo自适应:根据redo产生的速度还有脏页使用的比例来计算
- Mysql正常关闭
总结
每天进步一点点