1.1 select语句执行过程
下图是 MySQL 的一个简要架构图,从下图你可以很清晰的看到用户的 SQL 语句在 MySQL 内部是如何执行的。
先简单介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图,
连接器: 身份认证和权限相关(登录 MySQL)。
查询缓存: 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。
分析器: 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
优化器: 按照 MySQL 认为最优的方案去执行。根据cost开销进行优化,比如走哪条索引、哪个表驱动,选择cost开销最小的执行计划去执行
执行器: 执行语句,然后从存储引擎返回数据
简单来说 MySQL 主要分为 Server 层和存储引擎层:
Server 层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binglog 日志模块。
存储引擎: 主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始就被当做默认存储引擎了。
2. update/insert/delete 语句执行过程
buffer bool: innodb为了提升读写效率,设计了一个缓冲区buffer bool 每次从磁盘读取固定大小的数据存储到缓冲区buffer pool。缓冲区还没有从内存区同步到磁盘的时候,叫做脏页,因为断电等其他操作可能会导致与磁盘数据不一致。由后台线程同步到磁盘,不断进行,动作叫刷脏。刷脏并不是时时进行,在同步过程中如果服务器重启或者断电?这时候数据一致性怎么保证?
redo log:mysql innodb为了解决这种情况设计了redolog,重启后查看redolog中还有没有没同步的数据,若有则同步,实现数据的持久性。那这样设计有什么漏洞吗?
先写内存,又要写redo log ,为什么不直接写磁盘呢?这里引申处个顺序IO和随机IO的问题,读取数据先要找到扇区,磁盘不停转动,如果存储数据是随机存储,需要不停的寻址,叫做随机IO,如果存储的数据在一个块区,叫做顺序IO。redo log 写入日志是采用的是顺序IO,减少了寻址次数,加快IO的读写速度。
redo log 默认 48M ib_logfile0 ib_logfile1 ,记录在某个数据页进行了什么修改,属于物理日志。redolog 写满了触发刷盘操作,可以尽量设置的大一点,延缓redolog 的刷盘频率。
undo log: 记录事物发生之前的数据状态,发生异常时候回滚,保证数据的原子性。作用场景:如果一个操作包含多个sql语句,如果执行了一半失败了,保证所有的sql失败或者成功,实现原子性。没有独立的日志~
根据上述我们可以总结出一条更新语句的执行流程:
update table set name=“new name”
1、事物开始,从内存buffer pool 或磁盘data file 取到这条数据的数据页面,返回给Selver执行器
2.执行器修改这条数据的值如:set name=“new name”
3.记录name = oldname 到 undolog
4.记录name=newname 到 redolog
5.调用存储引擎innodb接口,记录修改后的数据页到buffer pool
6.事物提交
总结:在buffer pool 即内存中修改,修改完成后提交到磁盘。undolog 记录修改前数据,redolog 记录修改后数据。
log buffer buffer pool 的内存缓冲区 默认提交事物时候log buffer 提交 进行刷盘。
change buffer 是buffer pool 一部分。若缓冲区数据是非唯一索引,且不存在重复数据,这种情况也就不需要从磁盘中加载数据判断数据非唯一性。可把修改数据放在缓存中,提升读写效率。根据页面场景调整change buffer大小
一般占到机器80%,提高读写效率
buffer pool LRU 内存淘汰算法 ,根据热点数据进行淘汰。新查询或者进来的数据放到头部,不访问的数据放到链表尾部。类似JVM 热数据、冷数据区~
binlog: Server 层日志。非innodb独有。以事件的形式记录的DDL、DML日志,记录的是操作而不是数据值,属于逻辑值。可用于实现主从复制。和数据恢复(需要定时记录全量日志,先恢复全量数据,再根据binlog日志进行数据更新)
崩溃恢复时根据binlog日志记录,判断是否需要提交或回滚,走到了第6步则提交,否则回滚。
3. 总结
MySQL 主要分为 Server 层和引擎层,Server 层主要包括连接器、查询缓存、分析器、优化器、执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redolog 只有 InnoDB 有。
引擎层是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。
SQL 等执行过程分为两类,一类对于查询等过程如下:权限校验—》查询缓存—》分析器—》优化器—》权限校验—》执行器—》引擎
对于更新等语句执行流程如下:分析器----》权限校验----》执行器—》引擎—redo log prepare—》binlog—》redo log commit