【1】redo日志刷盘策略的选择建议。其实对于redo日志的三种刷盘策略,通常建议是设置为1。也就是说,提交事务的时候,redo日志必须是刷入磁盘文件里的,这样可以保证提交事务之后,数据是不会丢失的,因为有redo日志在磁盘文件里可以恢复你做的所有的修改。
如果要是选择0的话,可能你提交事务之后,mysql宕机,此时redo日志没有刷盘,导致内存里的redo日志丢失,你提交事务更新的数据就丢失了。
如果要是选择2的话,如果机器宕机,虽然提交事务的时候,redo日志进入os cache里了,但是还没有进入磁盘文件,此时机器宕机还是会导致os cache里的redo日志丢失。
所以对于数据库这样的系统而言,一般建议redo日志刷盘策略设置为1,保证提交事务之后,数据绝对不能丢失。
【2】MySQL binlog到底是什么东西?redo log偏向物理性质的重做日志,里面记录了类似这样的东西,对哪个数据页中的什么记录,做了个什么修改。redo log是属于InnoDB存储引擎特有的一个东西,binlog叫做归档日志,里面记录的是偏向于逻辑性的日志,类似于对user表中的id=10的这一行数据做了更新操作,更新以后的值是什么。binlog不是InnoDB存储引擎特有的日志文件,是属于mysql server自己的日志文件。
【3】提交事务的时候,同时会写入binlog。我们在提交事务的时候,会把redo log日志写入磁盘文件中去。然后其实在提交事务的时候,还会把这次更新对应的binlog日志写入到磁盘文件中去。
执行器会负责跟InnoDB进行交互,包括从磁盘里加载数据到Buffer Pool中进行缓存,包括写入undo日志,包括更新Buffer Pool里的数据,以及写入redo log buffer,redo log刷入磁盘,写binog,等等。执行器是一个非常核心的组件,负责跟存储引擎配合完成一个SQL语句在磁盘与内存层面的全部数据更新操作。
【4】binlog日志的刷盘策略分析。对于binlog日志,也有不同的刷盘策略,有一个sync_binlog参数可以控制binlog的刷盘策略,他的默认值是0,此时你把binlog写入磁盘的时候,其实不是直接进入磁盘文件,而是进入os cache内存缓存。如果此时宕机,那么你在os cache里的binlog日志是会丢失的。
如果要是把sync_binlog参数设置为1的话,那么此时会强制在提交事务的时候,把binlog直接写入到磁盘文件里去,那么这样提交事务之后,哪怕机器宕机,磁盘上的binlog是不会丢失的。
【5】基于binlog和redo log完成事务的提交。当我们把binlog写入磁盘文件之后,接着就会完成最终的事务提交,此时会把本次更新对应的binlog文件名称和这次更新的binlog日志在文件里的位置,都写入到redo log日志文件里去,同时在redo log日志文件里写入一个commit标记。在完成这个事情之后,才算是最终完成了事务的提交。
【6】最后一步在redo日志中写入commit标记的意义是什么?其实是用来保持redo log日志与binlog日志一致的。我们在提交事务的时候,只有
[1]redo日志刷入磁盘,
[2]binlog写入磁盘,
[3]对应的binlog文件名称和这次更新的binlog日志在文件里的位置,都写入到redo log日志文件里去,同时在redo log日志文件里写入一个commit标记
这3个条件都执行完毕,才算是提交了事务。如果没有最终的事务commit标记在redo日志里面,所以此次事务可以判定为不成功。必须是redo log中写入最终的事务commit标记了,然后此时事务提交成功,而且redo log里有本次更细对应的日志,binlog里也有本次更新对应的日志,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完全是一致的。
网友评论