]> git.saurik.com Git - redis.git/blobdiff - src/diskstore.c
Merge pull request #58 from hampus/fix-autorewrite
[redis.git] / src / diskstore.c
index 447f10b36c4369a05e5a58037df3faed219d52a9..9e86364e9c2ddd0e9cd54d8092e8bca2bcdeb76a 100644 (file)
@@ -183,14 +183,14 @@ int dsKeyToPath(redisDb *db, char *buf, robj *key) {
     return (buf-origbuf)+41;
 }
 
-int dsSet(redisDb *db, robj *key, robj *val) {
+int dsSet(redisDb *db, robj *key, robj *val, time_t expire) {
     char buf[1024], buf2[1024];
     FILE *fp;
     int retval, len;
 
     len = dsKeyToPath(db,buf,key);
     memcpy(buf2,buf,len);
-    snprintf(buf2+len,sizeof(buf2)-len,"_%ld_%ld",(long)time(NULL),(long)val);
+    snprintf(buf2+len,sizeof(buf2)-len,"-%ld-%ld",(long)time(NULL),(long)val);
     while ((fp = fopen(buf2,"w")) == NULL) {
         if (errno == ENOSPC) {
             redisLog(REDIS_WARNING,"Diskstore: No space left on device. Please make room and wait 30 seconds for Redis to continue.");
@@ -201,7 +201,7 @@ int dsSet(redisDb *db, robj *key, robj *val) {
             redisPanic("Unrecoverable diskstore error. Exiting.");
         }
     }
-    if ((retval = rdbSaveKeyValuePair(fp,db,key,val,time(NULL))) == -1)
+    if ((retval = rdbSaveKeyValuePair(fp,key,val,expire,time(NULL))) == -1)
         return REDIS_ERR;
     fclose(fp);
     if (retval == 0) {
@@ -401,6 +401,8 @@ void *dsRdbSave_thread(void *arg) {
                 readdir_r(dir,&de,&dp);
                 if (dp == NULL) break;
                 if (dp->d_name[0] == '.') continue;
+                /* If there is a '-' char in the file name, it's a temp file */
+                if (strchr(dp->d_name,'-') != NULL) continue;
 
                 /* Emit the SELECT DB opcode if needed. */
                 dbid = dsGetDbidFromFilename(dp->d_name);
@@ -454,7 +456,7 @@ void *dsRdbSave_thread(void *arg) {
     /* Use RENAME to make sure the DB file is changed atomically only
      * if the generate DB file is ok. */
     if (rename(tmpfile,filename) == -1) {
-        redisLog(REDIS_WARNING,"Error moving temp DB file on the final destination: %s", strerror(errno));
+        redisLog(REDIS_WARNING,"Error moving temp DB file on the final destination: %s (diskstore)", strerror(errno));
         unlink(tmpfile);
         dsRdbSaveSetState(REDIS_BGSAVE_THREAD_DONE_ERR);
         return NULL;
@@ -472,7 +474,7 @@ werr:
     return NULL;
 }
 
-int dsRdbSave(char *filename) {
+int dsRdbSaveBackground(char *filename) {
     pthread_t thread;
 
     if (pthread_create(&thread,NULL,dsRdbSave_thread,zstrdup(filename)) != 0) {
@@ -484,3 +486,24 @@ int dsRdbSave(char *filename) {
         return REDIS_OK;
     }
 }
+
+int dsRdbSave(char *filename) {
+    /* A blocking save is actually a non blocking save... just we wait
+     * for it to terminate in a non-busy loop. */
+
+    redisLog(REDIS_NOTICE,"Starting a blocking SAVE (BGSAVE + blocking wait)");
+    server.dirty_before_bgsave = server.dirty;
+    if (dsRdbSaveBackground(filename) == REDIS_ERR) return REDIS_ERR;
+    while(1) {
+        usleep(1000);
+        int state;
+
+        pthread_mutex_lock(&server.bgsavethread_mutex);
+        state = server.bgsavethread_state;
+        pthread_mutex_unlock(&server.bgsavethread_mutex);
+
+        if (state == REDIS_BGSAVE_THREAD_DONE_OK ||
+            state == REDIS_BGSAVE_THREAD_DONE_ERR) break;
+    }
+    return REDIS_OK;
+}