append only mode is now able to translate EXPIRE into EXPIREAT transparently

This commit is contained in:
antirez 2009-10-30 17:20:24 +01:00
parent 0154acdc57
commit 4e141d5a21
2 changed files with 34 additions and 7 deletions

26
redis.c
View File

@ -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}
};

View File

@ -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 ###############################