diff options
Diffstat (limited to 'src/rdb.c')
-rw-r--r-- | src/rdb.c | 76 |
1 files changed, 58 insertions, 18 deletions
@@ -88,6 +88,11 @@ void rdbReportError(int corruption_error, int linenum, char *reason, ...) { /* If we're loading an rdb file form disk, run rdb check (and exit) */ serverLog(LL_WARNING, "%s", msg); char *argv[2] = {"",rdbFileBeingLoaded}; + if (anetIsFifo(argv[1])) { + /* Cannot check RDB FIFO because we cannot reopen the FIFO and check already streamed data. */ + rdbCheckError("Cannot check RDB that is a FIFO: %s", argv[1]); + return; + } redis_check_rdb_main(2,argv,NULL); } else if (corruption_error) { /* In diskless loading, in case of corrupt file, log and exit. */ @@ -1437,31 +1442,29 @@ werr: /* Write error. */ return C_ERR; } -/* Save the DB on disk. Return C_ERR on error, C_OK on success. */ -int rdbSave(int req, char *filename, rdbSaveInfo *rsi, int rdbflags) { - char tmpfile[256]; +static int rdbSaveInternal(int req, const char *filename, rdbSaveInfo *rsi, int rdbflags) { char cwd[MAXPATHLEN]; /* Current working dir path for error messages. */ - FILE *fp = NULL; rio rdb; int error = 0; + int saved_errno; char *err_op; /* For a detailed log */ - snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid()); - fp = fopen(tmpfile,"w"); + FILE *fp = fopen(filename,"w"); if (!fp) { + saved_errno = errno; char *str_err = strerror(errno); char *cwdp = getcwd(cwd,MAXPATHLEN); serverLog(LL_WARNING, "Failed opening the temp RDB file %s (in server root dir %s) " "for saving: %s", - tmpfile, + filename, cwdp ? cwdp : "unknown", str_err); + errno = saved_errno; return C_ERR; } rioInitWithFile(&rdb,fp); - startSaving(RDBFLAGS_NONE); if (server.rdb_save_incremental_fsync) { rioSetAutoSync(&rdb,REDIS_AUTOSYNC_BYTES); @@ -1481,7 +1484,46 @@ int rdbSave(int req, char *filename, rdbSaveInfo *rsi, int rdbflags) { serverLog(LL_NOTICE,"Unable to reclaim cache after saving RDB: %s", strerror(errno)); } if (fclose(fp)) { fp = NULL; err_op = "fclose"; goto werr; } - fp = NULL; + + return C_OK; + +werr: + saved_errno = errno; + serverLog(LL_WARNING,"Write error while saving DB to the disk(%s): %s", err_op, strerror(errno)); + if (fp) fclose(fp); + unlink(filename); + errno = saved_errno; + return C_ERR; +} + +/* Save DB to the file. Similar to rdbSave() but this function won't use a + * temporary file and won't update the metrics. */ +int rdbSaveToFile(const char *filename) { + startSaving(RDBFLAGS_NONE); + + if (rdbSaveInternal(SLAVE_REQ_NONE,filename,NULL,RDBFLAGS_NONE) != C_OK) { + int saved_errno = errno; + stopSaving(0); + errno = saved_errno; + return C_ERR; + } + + stopSaving(1); + return C_OK; +} + +/* Save the DB on disk. Return C_ERR on error, C_OK on success. */ +int rdbSave(int req, char *filename, rdbSaveInfo *rsi, int rdbflags) { + char tmpfile[256]; + char cwd[MAXPATHLEN]; /* Current working dir path for error messages. */ + + startSaving(RDBFLAGS_NONE); + snprintf(tmpfile,256,"temp-%d.rdb", (int) getpid()); + + if (rdbSaveInternal(req,tmpfile,rsi,rdbflags) != C_OK) { + stopSaving(0); + return C_ERR; + } /* Use RENAME to make sure the DB file is changed atomically only * if the generate DB file is ok. */ @@ -1499,7 +1541,12 @@ int rdbSave(int req, char *filename, rdbSaveInfo *rsi, int rdbflags) { stopSaving(0); return C_ERR; } - if (fsyncFileDir(filename) == -1) { err_op = "fsyncFileDir"; goto werr; } + if (fsyncFileDir(filename) != 0) { + serverLog(LL_WARNING, + "Failed to fsync directory while saving DB: %s", strerror(errno)); + stopSaving(0); + return C_ERR; + } serverLog(LL_NOTICE,"DB saved on disk"); server.dirty = 0; @@ -1507,13 +1554,6 @@ int rdbSave(int req, char *filename, rdbSaveInfo *rsi, int rdbflags) { server.lastbgsave_status = C_OK; stopSaving(1); return C_OK; - -werr: - serverLog(LL_WARNING,"Write error saving DB on disk(%s): %s", err_op, strerror(errno)); - if (fp) fclose(fp); - unlink(tmpfile); - stopSaving(0); - return C_ERR; } int rdbSaveBackground(int req, char *filename, rdbSaveInfo *rsi, int rdbflags) { @@ -3361,7 +3401,7 @@ int rdbLoad(char *filename, rdbSaveInfo *rsi, int rdbflags) { /* Reclaim the cache backed by rdb */ if (retval == C_OK && !(rdbflags & RDBFLAGS_KEEP_CACHE)) { /* TODO: maybe we could combine the fopen and open into one in the future */ - rdb_fd = open(server.rdb_filename, O_RDONLY); + rdb_fd = open(filename, O_RDONLY); if (rdb_fd > 0) bioCreateCloseJob(rdb_fd, 0, 1); } return (retval==C_OK) ? RDB_OK : RDB_FAILED; |