innoDB存储引擎架构设计

一. innoDB的核心是Buffer pool(缓冲池)

1.mysql 执行器,在执行语句的时候,先看看缓冲池有没有数据,如果没有,才会从磁盘里面刷数据进缓冲池。

2.缓冲池的缓存被修改后且提交事务后,会随机将数据刷回磁盘

 

二.事务没提交前,缓存被修改了,想回滚数据怎么办?

1.缓冲池在修改数据的时候,会先把旧数据写一份进undo日志文件,确保提交事务之前都可以回滚数据。

 

三。如果在提交事务后,缓冲池修改过的数据,还没来得及刷入磁盘,突发宕机,怎么办?

1.innoDB存储引擎在更新完数据的时候,会将数据写入一个叫 Redo Log Buffer 的内存中。

2.Redo Log Buffer  的提交策略是通过 innodb_flush_log_at_trx_commit 参数配置的

(1). 配置0的时候,写入内存,不提交到磁盘。这种情况mysql宕机,缓存数据都找不回来。

(2). 配置1的时候,写入内存,并且会写到磁盘,如果mysql宕机,不会丢失数据,重启mysql的时候,会根据redo 日志文件恢复数据。

(3). 配置2的时候,把redo日志写入磁盘文件对应的os cache缓存里去,而不是直接进入磁盘文件,可能1秒后才会把os cache里的数据写入到磁盘文件里去。这种模式下,你提交事务之后,redo log可能仅仅停留在os cache内存缓存里,没实际进入磁盘文件,万一此时你要是机器宕机了,那么os cache里的redo log就会丢失,同样会让你感觉提交事务了,结果数据丢了,看下图。

四.还缺少一个binlog日志才能算一个事务的提交成功

1.提交事务的时候,同时会写入binlog。

2.binlog日志的刷盘策略

(1).对于binlog日志,其实也有不同的刷盘策略,有一个sync_binlog参数可以控制binlog的刷盘策略,他的默认值是0,此时你把binlog写入磁盘的时候,其实不是直接进入磁盘文件,而是进入os cache内存缓存。所以跟之前分析的一样,如果此时机器宕机,那么你在os cache里的binlog日志是会丢失的.

(2).如果要是把sync_binlog参数设置为1的话,那么此时会强制在提交事务的时候,把binlog直接写入到磁盘文件里去,那么这样提交事务之后,哪怕机器宕机,磁盘上的binlog是不会丢失的

3.基于binlog和redo log完成事务的提交

当我们把binlog写入磁盘文件之后,接着就会完成最终的事务提交,此时会把本次更新对应的binlog文件名称和这次更新的binlog日志在文件里的位置,都写入到redo log日志文件里去,同时在redo log日志文件里写入一个commit标记。在完成这个事情之后,才算最终完成了事务的提交

4.最后一步在redo日志中写入commit标记的意义是什么?

说白了,他其实是用来保持redo log日志与binlog日志一致的。我们来举个例子,假设我们在提交事务的时候,一共有上图中的5、6、7三个步骤,必须是三个步骤都执行完毕,才算是提交了事务。那么在我们刚完成步骤5的时候,也就是redo log刚刷入磁盘文件的时候,mysql宕机了,此时怎么办?这个时候因为没有最终的事务commit标记在redo日志里,所以此次事务可以判定为不成功。不会说redo日志文件里有这次更新的日志,但是binlog日志文件里没有这次更新的日志,不会出现数据不一致的问题。如果要是完成步骤6的时候,也就是binlog写入磁盘了,此时mysql宕机了,怎么办?同理,因为没有redo log中的最终commit标记,因此此时事务提交也是失败的。必须是在redo log中写入最终的事务commit标记了,然后此时事务提交成功,而且redo log里有本次更新对应的日志,binlog里也有本次更新对应的日志 ,redo log和binlog完全是一致的。

 

五。总结一下InnoDB存储引擎的架构原理

在你执行更新的时候,每条SQL语句,都会对应修改buffer pool里的缓存数据、写undo日志、写redo log buffer几个步骤;但是当你提交事务的时候,一定会把redo log刷入磁盘,binlog刷入磁盘,完成redo log中的事务commit标记;最后后台的IO线程会随机的把buffer pool里的脏数据刷入磁盘里去。

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页