X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/cb9b35c8cafc703ea5f2754b2961c9a3268c35d5..419e1cca74102440d5ce174fbbf36d81a9b8956a:/src/rdb.c diff --git a/src/rdb.c b/src/rdb.c index 6b6b6ab6..02317fda 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -399,13 +399,9 @@ off_t rdbSavedObjectLen(robj *o) { * On error -1 is returned. * On success if the key was actaully saved 1 is returned, otherwise 0 * is returned (the key was already expired). */ -int rdbSaveKeyValuePair(FILE *fp, redisDb *db, robj *key, robj *val, - time_t now) +int rdbSaveKeyValuePair(FILE *fp, robj *key, robj *val, + time_t expiretime, time_t now) { - time_t expiretime; - - expiretime = getExpire(db,key); - /* Save the expire time */ if (expiretime != -1) { /* If this key is already expired skip it */ @@ -437,7 +433,8 @@ int rdbSave(char *filename) { snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid()); fp = fopen(tmpfile,"w"); if (!fp) { - redisLog(REDIS_WARNING, "Failed saving the DB: %s", strerror(errno)); + redisLog(REDIS_WARNING, "Failed opening .rdb for saving: %s", + strerror(errno)); return REDIS_ERR; } if (fwrite("REDIS0001",9,1,fp) == 0) goto werr; @@ -459,9 +456,11 @@ int rdbSave(char *filename) { while((de = dictNext(di)) != NULL) { sds keystr = dictGetEntryKey(de); robj key, *o = dictGetEntryVal(de); + time_t expire; initStaticStringObject(key,keystr); - if (rdbSaveKeyValuePair(fp,db,&key,o,now) == -1) goto werr; + expire = getExpire(db,&key); + if (rdbSaveKeyValuePair(fp,&key,o,expire,now) == -1) goto werr; } dictReleaseIterator(di); } @@ -496,22 +495,23 @@ werr: int rdbSaveBackground(char *filename) { pid_t childpid; - if (server.bgsavechildpid != -1) return REDIS_ERR; + if (server.bgsavechildpid != -1 || + server.bgsavethread != (pthread_t) -1) return REDIS_ERR; server.dirty_before_bgsave = server.dirty; + if (server.ds_enabled) { + cacheForcePointInTime(); + return dsRdbSaveBackground(filename); + } + if ((childpid = fork()) == 0) { int retval; /* Child */ if (server.ipfd > 0) close(server.ipfd); if (server.sofd > 0) close(server.sofd); - if (server.ds_enabled) { - cacheForcePointInTime(); - dsRdbSave(filename); - } else { - rdbSave(filename); - } + retval = rdbSave(filename); _exit((retval == REDIS_OK) ? 0 : 1); } else { /* Parent */ @@ -950,10 +950,7 @@ eoferr: /* unexpected end of file is handled here with a fatal exit */ } /* A background saving child (BGSAVE) terminated its work. Handle this. */ -void backgroundSaveDoneHandler(int statloc) { - int exitcode = WEXITSTATUS(statloc); - int bysignal = WIFSIGNALED(statloc); - +void backgroundSaveDoneHandler(int exitcode, int bysignal) { if (!bysignal && exitcode == 0) { redisLog(REDIS_NOTICE, "Background saving terminated with success"); @@ -963,11 +960,37 @@ void backgroundSaveDoneHandler(int statloc) { redisLog(REDIS_WARNING, "Background saving error"); } else { redisLog(REDIS_WARNING, - "Background saving terminated by signal %d", WTERMSIG(statloc)); + "Background saving terminated by signal %d", bysignal); rdbRemoveTempFile(server.bgsavechildpid); } server.bgsavechildpid = -1; + server.bgsavethread = (pthread_t) -1; + server.bgsavethread_state = REDIS_BGSAVE_THREAD_UNACTIVE; /* Possibly there are slaves waiting for a BGSAVE in order to be served * (the first stage of SYNC is a bulk transfer of dump.rdb) */ updateSlavesWaitingBgsave(exitcode == 0 ? REDIS_OK : REDIS_ERR); } + +void saveCommand(redisClient *c) { + if (server.bgsavechildpid != -1 || server.bgsavethread != (pthread_t)-1) { + addReplyError(c,"Background save already in progress"); + return; + } + if (rdbSave(server.dbfilename) == REDIS_OK) { + addReply(c,shared.ok); + } else { + addReply(c,shared.err); + } +} + +void bgsaveCommand(redisClient *c) { + if (server.bgsavechildpid != -1 || server.bgsavethread != (pthread_t)-1) { + addReplyError(c,"Background save already in progress"); + return; + } + if (rdbSaveBackground(server.dbfilename) == REDIS_OK) { + addReplyStatus(c,"Background saving started"); + } else { + addReply(c,shared.err); + } +}