summaryrefslogtreecommitdiff
path: root/src/rdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rdb.c')
-rw-r--r--src/rdb.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/src/rdb.c b/src/rdb.c
index a2be21ccb..c52d8faf7 100644
--- a/src/rdb.c
+++ b/src/rdb.c
@@ -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;