X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/f03fe802b79d1d41377016fd9755523dfae102e9..69298a05eb23cbbf60f9008faa2e11866ab4352a:/src/diskstore.c diff --git a/src/diskstore.c b/src/diskstore.c index 447f10b3..9e86364e 100644 --- a/src/diskstore.c +++ b/src/diskstore.c @@ -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; +}