InnoDB存储引擎执行原理深度剖析
1.undo log和redo log了解过吗?它们的作用分别是什么?
2.redo log是如何保证事务不丢失的?
3.mysql的事务是先提交还是先刷盘?
Mysql架构和InnoDB存储引擎-流程图解析
前台操作触发Mysql服务器执行请求
前台用户各种操作触发后台sql执行,通过web项目中自带的数据库连接池:如dbcp、c3p0、druid等,与数据库服务器的数据库连接池建立网络连接;
数据库连接池中的线程监听到请求后,将接收到的sql语句通过SQL接口响应给查询解析器,查询解析器将sql按照sql的语法解析出查询哪个表的哪些字段,查询条件是啥;再通过查询优化器处理,选择该sq最优的一套执行计划,然后执行器负责调用存储引擎的一系列接口,执行该计划而完成整个sql语句的执行,如下图所示:
InnoDB存储引擎-缓冲池中完成更新的基本操作
具体执行这些执行计划得要存储引擎来完成,如图所示,首次更新users表中id=10的这条数据,缓冲池中一开始肯定没有该条数据的,得要先从磁盘中将被更新数据的原始数据加载到缓冲池中(这里涉及到的innodb buffer暂时不讲)。
同时为了保证并发更新数据安全问题,会对这条数据先加锁,防止其他事务进行更新。
接着将更新前的值先备份写入到undo log中(便于事务回滚时取旧数据),比如update语句即存储被更新字段之前的值。
最后更新缓存页中的数据为最新的数据,至此就完成了在缓冲池中的执行流程,如下图所示:
Redo Log和BinLog保证事务的可靠性
缓冲池中更新完数据后,需要将本次的更新信息顺序写到Redo Log日志以及Binlog日志中(此时信息还在内存中,后续的刷盘策略如图所示),一般我们为了保证数据不丢失会配置双1策略,Redo Log落盘后,写Binlog落盘,再将Binlog的文件名、文件所在路径信息以及commit标记给同步顺序写到Redo log中(其中以commit标记是否更新到Redo Log中,是判定事务是否成功提交的一个比较重要的标准),Redo Log和BinLog分别在物理和逻辑层面为本次事务、提供数据上的一致性保障,如下图所示:
将事务的操作持久化
前面一些列操作执行成功后,InnoDB存储引擎后台有一个IO线程,会在数据库压力的低峰期间时如凌晨时分,将缓冲池中被事务更新、但还没来得及写到磁盘中的数据(脏数据,因为磁盘数据和内存数据已经不一致了)给刷到磁盘中,完成事务的持久化,如下图所示: