diff --git a/redis.c b/redis.c index 839b0b3b3..f57ec8169 100644 --- a/redis.c +++ b/redis.c @@ -1036,7 +1036,7 @@ static void initServerConfig() { server.glueoutputbuf = 1; server.daemonize = 0; server.appendonly = 0; - server.appendfsync = APPENDFSYNC_NO; + server.appendfsync = APPENDFSYNC_ALWAYS; server.lastfsync = time(NULL); server.appendfd = -1; server.appendseldb = -1; /* Make sure the first time will not match */ @@ -1672,6 +1672,7 @@ static void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv int j; ssize_t nwritten; time_t now; + robj *tmpargv[3]; /* The DB this command was targetting is not the same as the last command * we appendend. To issue a SELECT command is needed. */ @@ -1683,6 +1684,21 @@ static void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv strlen(seldb),seldb); server.appendseldb = dictid; } + + /* "Fix" the argv vector if the command is EXPIRE. We want to translate + * EXPIREs into EXPIREATs calls */ + if (cmd->proc == expireCommand) { + long when; + + tmpargv[0] = createStringObject("EXPIREAT",8); + tmpargv[1] = argv[1]; + incrRefCount(argv[1]); + when = time(NULL)+strtol(argv[2]->ptr,NULL,10); + tmpargv[2] = createObject(REDIS_STRING, + sdscatprintf(sdsempty(),"%ld",when)); + argv = tmpargv; + } + /* Append the actual command */ buf = sdscatprintf(buf,"*%d\r\n",argc); for (j = 0; j < argc; j++) { @@ -1696,6 +1712,13 @@ static void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv if (o != argv[j]) decrRefCount(o); } + + /* Free the objects from the modified argv for EXPIREAT */ + if (cmd->proc == expireCommand) { + for (j = 0; j < 3; j++) + decrRefCount(argv[j]); + } + /* We want to perform a single write. This should be guaranteed atomic * at least if the filesystem we are writing is a real physical one. * While this will save us against the server being killed I don't think @@ -5450,6 +5473,7 @@ static struct redisFunctionSym symsTable[] = { {"zremCommand",(unsigned long)zremCommand}, {"rdbSaveDoubleValue",(unsigned long)rdbSaveDoubleValue}, {"rdbLoadDoubleValue",(unsigned long)rdbLoadDoubleValue}, +{"feedAppendOnlyFile",(unsigned long)feedAppendOnlyFile}, {NULL,0} }; diff --git a/redis.conf b/redis.conf index a7ec36a08..72cba4ab2 100644 --- a/redis.conf +++ b/redis.conf @@ -124,9 +124,9 @@ databases 16 # # The name of the append only file is "appendonly.log" -# appendonly yes +appendonly no -# The fsync() calls tells the Operating System to actually write data on disk +# The fsync() call tells the Operating System to actually write data on disk # instead to wait for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP. # @@ -136,12 +136,15 @@ databases 16 # always: fsync after every write to the append only log . Slow, Safest. # everysec: fsync only if one second passed since the last fsync. Compromise. # -# The default is "no" since it's faster and anyway safer than snapshots from -# the point of view of durability of the latest records modified. +# The default is "always" that's the safer of the options. It's up to you to +# understand if you can relax this to "everysec" that will fsync every second +# or to "no" that will let the operating system flush the output buffer when +# it want, for better performances (but if you can live with the idea of +# some data loss consider the default persistence mode that's snapshotting). -appendfsync no -# appendfsync always +appendfsync always # appendfsync everysec +# appendfsync no ############################### ADVANCED CONFIG ###############################