前言:
【本期主要将SQL执行器调用存储引擎接口后,大体的执行流程,以及各个日志文件的作用】
1.InnoDB存储引擎
2.Buffer pool缓冲区
3.undo log日志文件
4.redo log日志文件以及redo log buffer缓冲区与redo log buffer缓冲区刷入disk的配置机制
5.binlog日志文件以及sync_binlog参数的设置
6.mysql后台线程将Buffer pool修改后的数据刷入磁盘
1.InnoDB存储引擎
这个相信每个人都知道这个存储引擎,引擎嘛,通俗易懂的理解就是发动机,车子没发动机怎么能跑呢,所以这个存储引擎才是整个MySQL的发动机,也是MySQL的核心,上一讲讲到经过SQL解析器,SQL查询优化器,SQL执行组件会不断的调用存储引擎接口完成SQL的执行操作【后续文章慢慢会引出这个存储引擎中的N个组件和知识模块】;
2. Buffer pool缓冲区
缓冲区顾名思义就是内存操作,如果每个SQL都要去disk操作,这些IO会极大的影响到执行SQL的效率,大白话一点就是我们平时写业务逻辑代码的时候,需要去做的缓存,像平时用到的redis,等等,redis本人也修炼了,博客中有一些redis的散文知识点,后期可能会更加系统的再出几篇,屁话不多说:简单理解一下buffer pool缓存区的作用(在InnoDB存储引擎中buffer pool缓冲区是放在内存中的非常重要的组件,里面会缓存很多的数据,便于查询的时候,缓冲池中有数据【目前这样理解,但是其实buffer pool中放的是缓存页,一个缓存页的大小16KB】,就不走disk查询了。)
3. undo log日志文件
例如现在执行一个事务,那么一个事务有多条SQL执行语句,例如:insert,update,delete等等,那么如何事务执行失败了,MySQL如何做回滚操作呢?实际上MySQL就是依靠undo log日志文件进行回滚操作的,简单举个例子:如果进行了一个update操作,原始值name = a,执行update之后 name = b了,此时undo log日志文件中就会记录旧的name = a数据,当然还会记录此数据行的主键等等,例如事务执行失败了,会基于旧值进行回滚操作。以此类推,如果执行了一次insert操作,那么执行失败之后,undo log日志文件中就会有对应主键的delete操作,事务失败就会执行delete操作,恢复数据。
4. redo log日志文件以及redo log buffer缓冲区与redo logBbuffer缓冲区日志刷入disk的配置机制
4.1:redo log日志文件是什么?
redo log日志文件实际上就是在buffer pool中做了修改后的数据日志记录,这个redo log的日志记录的作用主要就是为了防止在buffer pool中做完了操作,buffer pool中的数据还没有来得及刷盘,导致内存中进行修改过的数据丢失。【这里可能会有点点绕,举个例子:例如age = 2,执行了一条update语句 age = 3了,此时的操作是在buffer pool缓冲区中做的,redo log日志做了修改记录,并已经刷入disk了, 但是buffer pool中修改过的数据还没有来得及刷入磁盘,MySQL直接宕机了,就会出现这个数据丢失的问题,那么redo log日志主要做的就是记录更新后的日志记录,也就是undo log记录修改前的,redo log则是记录修改后的,MySQL恢复故障重启之后,就可以基于redo log恢复buffer pool中的更新操作了】
4.2:redo log buffer
redo log buffer也是一块缓冲区,说白了这些个缓冲区都是为了提高性能的,实际上buffer pool更新完成之后,会先将redo log日志信息写入到redo log buffer缓冲区中,基于内存操作,效率更高,然后再每隔一段时间刷入redo log磁盘文件中【此时就会出现新问题:MySQL宕机,buffer pool缓冲区的数据丢失了,redo log日志也还没有来得及刷盘,此时不也是发生了数据丢失?对的,在这种极致的情况下会出现这种情况,引出来redo log buffer的刷盘配置策略】
4.3:redo log buffer 刷盘参数配置:innodb_flush_log_at_trx_commit
参数:0:不刷盘、1:提交到redo log buffer即刻刷盘、2:1秒后强制刷盘 也就是说,如果要保证完全的数据不丢失,将innodb_flush_log_at_trx_commit配置为1,即刻刷盘即可。0一般是不会配置的,1是默认值;
5. binlog日志以及sync_binlog参数的设置
5.1:binlog日志的作用
关于binlog日志在实际工作中的作用还是十分多的,之前在rocket MQ文章中写到了,实际上这个binlog日志记录的就是MySQL增删改的操作记录。例如高可用架构,MySQL的主从架构,读写分离,都是后台线程通过binlog日志完成数据同步的,特点:有点点绕,binlog不是InnoDB存储引擎特有的日志文件,是属于MySQL server自己的日志文件,记录的是偏向于逻辑性的日志,更新前的值和更新后的值分别是什么。
5.2:sync_binlog参数设置
也就是说设置这个binlog日志是否落盘,如果参数设置为1,提交事务的时候,直接将binlog写入磁盘文件,默认0,不写入磁盘。
6.mysql后台线程将Buffer pool修改后的数据刷入磁盘
这里特别强调一点点,循循渐进,慢慢深入,先摸概念,再探原理,MySQL后台线程会随机将buffer pool中的更新过的数据随机刷入到磁盘,覆盖disk上面的旧数据【PS:实际上刷入的是数据页】,欢迎留言哈,或者是继续往后看,会有解答。
以上就是:MySQL InnoDB存储引擎的架构设计,以及如何基于存储引擎完成一条更新语句的执行,在文章的末尾,简单的做个汇总总结以及图解:
总结:建议结合第一讲MySQL专题一
首先MySQL线程会从连接中监听SQL,监听到SQL后将SQL转交给SQL接口,然后SQL解析器进行SQL解析,解析完事之后交给SQL优化器进行查询最优SQL执行路径,完事执行器调用存储引擎接口执行SQL,实际上这里是会将该数据行所在的数据页加入到buffer pool缓冲区并加锁(变成缓存页),仅仅提一嘴,然后执行器在将更新前的数据行写入undo log日志,便于update在某种情况下例如事务操作失败后回滚,接着更新buffer pool缓存中的数据,写入redo log buffer或者是直接写redo log,根据参数不同,写入时机不同,记录更新后的数据,最后一步写入binlog 日志,也是根据不同策略选择是否刷盘,最后binlog 日志文件与位置写入redo log日志文件,并记入commit标识,这一步的意义:就是保持redo log日志文件与binlog日志文件一致,最后打完收工!
【贴图】