解决缺陷2
backgroundRewriteDoneHandler里同样的把close old-aof-file的工作交给backgroud thread来执行.
=========
856 /* Asynchronously close the overwritten AOF. */
857 if (oldfd != -1) bioCreateBackgroundJob(REDIS_BIO_CLOSE_FILE,(void*)(long)oldfd,NULL
这样关闭old-aof-file的工作被移交到后台任务执行,不再阻塞主线程了,不过没那么简单,如下的特殊场景需要额外处理.
bgrewriteaof start
aof disbled
bgrewriteaof stop
bgrewriteaof handler
在bgrewriteaof触发之后,关闭了aof功能,这样由于server.appendfd对应old-aof-file文件未被打开, 一旦rename new-aof old-aof, 则会触发一个unlink old-aof-file的行为, 而不是上面说的close才触发unlink行为.为了跳过这种状况,如果发现aof被关闭,通过打开old-aof-file文件增加引用计数的方法解决这个问题.
==========
810 if (server.appendfd == -1) {
811 /* AOF disabled */
812
813 /* Don't care if this fails: oldfd will be -1 and we handle that.
814 * One notable case of -1 return is if the old file does
815 * not exist. */
816 oldfd = open(server.appendfilename,O_RDONLY|O_NONBLOCK);
817 } else {
818 /* AOF enabled */
819 oldfd = -1; /* We'll set this to the current AOF filedes later. */
820 }
816行:如果处于aof关闭状态,则打开old-aof-file.
819行:aof已经是激活状态,不做任何操作.
这样rename就不再引发unlink old-aof-file, 不会再阻塞主线程.
处理完rename之后就要来处理old-aof-file了.如果aof是非激活状态,对于new-aof-file文件,我们关闭他即可不需要其它操作,这个close不会引发阻塞,因为这个文件的已经在生成new-aof-file文件的时候做过fsync了.
如果aof是激活状态, fsync行为递给后台去执行,这块的行为和缺陷1一样.
===========
840 if (server.appendfsync == APPENDFSYNC_ALWAYS)
841 aof_fsync(newfd);
842 else if (server.appendfsync == APPENDFSYNC_EVERYSEC)
843 aof_background_fsync(newfd);
解决缺陷3
引入了延迟bgrewriteaof来避免与bgsave同时写文件,而server.no_appendfsync_on_rewrite参数的设置又避免了bgrewriteaof时主线程出现fsync.
测试2.4.1的性能确实较之前版有较大的提升,以后会给出测试数据.