* 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 */
int j;
time_t now = time(NULL);
- /* FIXME: implement .rdb save for disk store properly */
- redisAssert(server.ds_enabled == 0);
+ if (server.ds_enabled) {
+ cacheForcePointInTime();
+ return dsRdbSave(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;
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);
}
int rdbSaveBackground(char *filename) {
pid_t childpid;
- if (server.bgsavechildpid != -1) return REDIS_ERR;
- redisAssert(server.ds_enabled == 0);
+ 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 (rdbSave(filename) == REDIS_OK) {
- _exit(0);
- } else {
- _exit(1);
- }
+ retval = rdbSave(filename);
+ _exit((retval == REDIS_OK) ? 0 : 1);
} else {
/* Parent */
if (childpid == -1) {
}
/* 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");
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);
+ }
+}