文章目录
- MySql redoLog和Redis Aof的刷盘策略理解
- 一、示图
- 二、Redis Aof
- 三、MySql Redo Log
- 四、关于fsync
- 五、参考
MySql redoLog和Redis Aof的刷盘策略理解
一、示图
- 按照上图理解,以Redis为例,在应用程序内部将写操作的命令顺序写入到AOF缓冲区,这个缓冲区内的数据在应用程序重启后就会丢失。
- 操作系统的文件系统内会对数据做缓冲,而不会每次对文件的操作都去写磁盘,这部分数据只要操作系统不重启,换言之服务器没问题就不会丢失,即使上层的应用重启也不会丢失。
- 最下面一层的是磁盘的数据,数据同步到磁盘之后,只要磁盘不发生硬件故障,理论上不会丢失,即使服务器重启。
二、Redis Aof
- 下面先看看Redis AOF的几个配置的理解
配置 | 含义 | 效率 | 安全 |
appendfsync=always | 同步持久化每一次修改操作 | 效率最低 | 安全最高,最多丢失一个事件循环的数据 |
appendfsync=everysec | 每秒向aof文件同步一次 | 效率最折中 | 安全最折中,最多丢失1S的数据(但是实际上是有可能大于1S的) |
appendfsync=no | 关闭向aof文件写入修改 | 效率最高 | 安全最低,最多上一次保存AOF文件到当前时刻的全部数据 |
always:写入+同步;每个事件循环,都会将aof_buf中的内容写入到aof文件,并且同步到aof文件,也就是会完成写入和同步两个过程,此种情况效率最低,安全性最高。
everysec:写入+每秒同步一次;每个事件循环,都会将aof_buf中的内容写入到aof文件,但是每间隔1S才会完成一个同步动作,此种情况效率和安全性折中。
no:写入+ 不同步;每个事件循环,都会将aof_buf中的内容写入到aof文件,同步动作交给操作系统完成,自己不管,此种情况效率最高安全性最低。
三、MySql Redo Log
- 我们知道RedoLog是MySql的重做日志,是可以保证数据安全的,在这里今天不讨论在Redo Log在MySql体系中的重要地位,也类比Redis 的Aof文件来看看他的刷盘策略。
配置 | 含义 | 效率 | 安全 |
innodb_flush_log_at_trx_commit=1(默认) | 每次事务提交的时候都调用fsync来写入到磁盘 | ||
innodb_flush_log_at_trx_commit=0(默认) | 事务commit的时候,不写入redo log file,而是通过master线程每秒操作一次,从redo log buffer写入到redo log file中 | ||
innodb_flush_log_at_trx_commit=2(默认) | 事务提交时将redo log buffer刷入redo log file,也即刷入系统文件缓存中,不进行fsync操作,由系统来进行fsync操作 |
1 :写入 + 同步; 每次提交事物都写盘,也就是执行写入和同步两个动作,类比redis的always策略。
0 :不写入 + 每秒写入一次; 每次提交事物都不写文件,也就是不执行写入动作,但是每秒执行一个写入动作,显然这种策略相对没那么安全,因为写入的数据还在缓存,服务器故障可能丢失。
2 :写入 + 不同步; 每次提交事物都执行写入动作,但是同步工作交给操作系统。
四、关于fsync
- fsync是系统命令,用于将数据同步到磁盘,即完成上面图中的第二个步骤。
- 当将数据写入文件时,内核通常先将该数据复制到一个缓冲区,如果该缓冲区尚未写满则并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时再将该缓冲排入输出队列,然后待其到达队首时,才进行实际的 I/O 。 操作,这种输出方式被成为延迟写。这样的方式提高了写入性能,但是导致有些情况即使写入了文件也不能保证该文件的内容同步到了磁盘,服务器宕机数据就丢失了,也就是完成了上图中写入的步骤但是没有完成同步的步骤,因此提高了该命令来刷盘。
- 在Linux下可以执行fsync来将缓存数据同步到磁盘。
- 前面提到的同步过程交给操作系统完成,至于操作系统什么时候做,这个取决于操作系统,可能是定时,或者是脏页比例达到多少之后同步都有可能。
五、参考
- [1] 函数sync、fsync与fdatasync总结整理