summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2020-03-03 14:58:11 +0100
committerantirez <antirez@gmail.com>2020-03-03 14:58:15 +0100
commit5e2319c3266c6a4e0a3745c6b3a6af63dc3d9a94 (patch)
tree1e9b7d01c6bbbbeafc6a15496f023746c98ab323
parent6dd8de177418da61e3d6466fe01fb5b3413c8308 (diff)
downloadredis-5e2319c3266c6a4e0a3745c6b3a6af63dc3d9a94.tar.gz
Remove RDB files used for replication in persistence-less instances.
-rw-r--r--src/replication.c48
-rw-r--r--src/server.c8
-rw-r--r--src/server.h1
3 files changed, 56 insertions, 1 deletions
diff --git a/src/replication.c b/src/replication.c
index c497051c8..e71b269d8 100644
--- a/src/replication.c
+++ b/src/replication.c
@@ -45,6 +45,11 @@ void replicationSendAck(void);
void putSlaveOnline(client *slave);
int cancelReplicationHandshake(void);
+/* We take a global flag to remember if this instance generated an RDB
+ * because of replication, so that we can remove the RDB file in case
+ * the instance is configured to have no persistence. */
+int RDBGeneratedByReplication = 0;
+
/* --------------------------- Utility functions ---------------------------- */
/* Return the pointer to a string representing the slave ip:listening_port
@@ -591,6 +596,10 @@ int startBgsaveForReplication(int mincapa) {
retval = C_ERR;
}
+ /* If we succeeded to start a BGSAVE with disk target, let's remember
+ * this fact, so that we can later delete the file if needed. */
+ if (retval == C_OK && !socket_target) RDBGeneratedByReplication = 1;
+
/* If we failed to BGSAVE, remove the slaves waiting for a full
* resynchronization from the list of slaves, inform them with
* an error about what happened, close the connection ASAP. */
@@ -883,6 +892,36 @@ void putSlaveOnline(client *slave) {
replicationGetSlaveName(slave));
}
+/* We call this function periodically to remove an RDB file that was
+ * generated because of replication, in an instance that is otherwise
+ * without any persistence. We don't want instances without persistence
+ * to take RDB files around, this violates certain policies in certain
+ * environments. */
+void removeRDBUsedToSyncReplicas(void) {
+ if (allPersistenceDisabled() && RDBGeneratedByReplication) {
+ client *slave;
+ listNode *ln;
+ listIter li;
+
+ int delrdb = 1;
+ listRewind(server.slaves,&li);
+ while((ln = listNext(&li))) {
+ slave = ln->value;
+ if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_START ||
+ slave->replstate == SLAVE_STATE_WAIT_BGSAVE_END ||
+ slave->replstate == SLAVE_STATE_SEND_BULK)
+ {
+ delrdb = 0;
+ break; /* No need to check the other replicas. */
+ }
+ }
+ if (delrdb) {
+ RDBGeneratedByReplication = 0;
+ unlink(server.rdb_filename);
+ }
+ }
+}
+
void sendBulkToSlave(connection *conn) {
client *slave = connGetPrivateData(conn);
char buf[PROTO_IOBUF_LEN];
@@ -894,7 +933,8 @@ void sendBulkToSlave(connection *conn) {
if (slave->replpreamble) {
nwritten = connWrite(conn,slave->replpreamble,sdslen(slave->replpreamble));
if (nwritten == -1) {
- serverLog(LL_VERBOSE,"Write error sending RDB preamble to replica: %s",
+ serverLog(LL_VERBOSE,
+ "Write error sending RDB preamble to replica: %s",
connGetLastError(conn));
freeClient(slave);
return;
@@ -1639,12 +1679,14 @@ void readSyncBulkPayload(connection *conn) {
"Failed trying to load the MASTER synchronization "
"DB from disk");
cancelReplicationHandshake();
+ if (allPersistenceDisabled()) unlink(server.rdb_filename);
/* Note that there's no point in restarting the AOF on sync failure,
it'll be restarted when sync succeeds or replica promoted. */
return;
}
/* Cleanup. */
+ if (allPersistenceDisabled()) unlink(server.rdb_filename);
zfree(server.repl_transfer_tmpfile);
close(server.repl_transfer_fd);
server.repl_transfer_fd = -1;
@@ -3149,6 +3191,10 @@ void replicationCron(void) {
}
}
+ /* Remove the RDB file used for replication if Redis is not running
+ * with any persistence. */
+ removeRDBUsedToSyncReplicas();
+
/* Refresh the number of slaves with lag <= min-slaves-max-lag. */
refreshGoodSlavesCount();
replication_cron_loops++; /* Incremented with frequency 1 HZ. */
diff --git a/src/server.c b/src/server.c
index bb8b3b103..a6d4b357e 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1455,12 +1455,20 @@ void updateDictResizePolicy(void) {
dictDisableResize();
}
+/* Return true if there are no active children processes doing RDB saving,
+ * AOF rewriting, or some side process spawned by a loaded module. */
int hasActiveChildProcess() {
return server.rdb_child_pid != -1 ||
server.aof_child_pid != -1 ||
server.module_child_pid != -1;
}
+/* Return true if this instance has persistence completely turned off:
+ * both RDB and AOF are disabled. */
+int allPersistenceDisabled(void) {
+ return server.saveparamslen == 0 && server.aof_state == AOF_OFF;
+}
+
/* ======================= Cron: called every 100 ms ======================== */
/* Add a sample to the operations per second array of samples. */
diff --git a/src/server.h b/src/server.h
index 87c293c26..5763671e4 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1786,6 +1786,7 @@ void loadingProgress(off_t pos);
void stopLoading(int success);
void startSaving(int rdbflags);
void stopSaving(int success);
+int allPersistenceDisabled(void);
#define DISK_ERROR_TYPE_AOF 1 /* Don't accept writes: AOF errors. */
#define DISK_ERROR_TYPE_RDB 2 /* Don't accept writes: RDB errors. */