Commit 8e555374 authored by antirez's avatar antirez
Browse files

Undo slaves state change on failed rdbSaveToSlavesSockets().

As Oran Agra suggested, in startBgsaveForReplication() when the BGSAVE
attempt returns an error, we scan the list of slaves in order to remove
them since there is no way to serve them currently.

However we check for the replication state BGSAVE_START, which was
modified by rdbSaveToSlaveSockets() before forking(). So when fork fails
the state of slaves remain BGSAVE_END and no cleanup is performed.

This commit fixes the problem by making rdbSaveToSlavesSockets() able to
undo the state change on fork failure.
parent 5f813035
...@@ -1649,27 +1649,43 @@ int rdbSaveToSlavesSockets(void) { ...@@ -1649,27 +1649,43 @@ int rdbSaveToSlavesSockets(void) {
exitFromChild((retval == C_OK) ? 0 : 1); exitFromChild((retval == C_OK) ? 0 : 1);
} else { } else {
/* Parent */ /* Parent */
zfree(clientids); /* Not used by parent. Free ASAP. */
server.stat_fork_time = ustime()-start; server.stat_fork_time = ustime()-start;
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */ server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000); latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
if (childpid == -1) { if (childpid == -1) {
serverLog(LL_WARNING,"Can't save in background: fork: %s", serverLog(LL_WARNING,"Can't save in background: fork: %s",
strerror(errno)); strerror(errno));
zfree(fds);
/* Undo the state change. The caller will perform cleanup on
* all the slaves in BGSAVE_START state, but an early call to
* replicationSetupSlaveForFullResync() turned it into BGSAVE_END */
listRewind(server.slaves,&li);
while((ln = listNext(&li))) {
client *slave = ln->value;
int j;
for (j = 0; j < numfds; j++) {
if (slave->id == clientids[j]) {
slave->replstate = SLAVE_STATE_WAIT_BGSAVE_START;
break;
}
}
}
close(pipefds[0]); close(pipefds[0]);
close(pipefds[1]); close(pipefds[1]);
return C_ERR; } else {
serverLog(LL_NOTICE,"Background RDB transfer started by pid %d",
childpid);
server.rdb_save_time_start = time(NULL);
server.rdb_child_pid = childpid;
server.rdb_child_type = RDB_CHILD_TYPE_SOCKET;
updateDictResizePolicy();
} }
serverLog(LL_NOTICE,"Background RDB transfer started by pid %d",childpid); zfree(clientids);
server.rdb_save_time_start = time(NULL);
server.rdb_child_pid = childpid;
server.rdb_child_type = RDB_CHILD_TYPE_SOCKET;
updateDictResizePolicy();
zfree(fds); zfree(fds);
return C_OK; return (childpid == -1) ? C_ERR : C_OK;
} }
return C_OK; /* unreached */ return C_OK; /* Unreached. */
} }
void saveCommand(client *c) { void saveCommand(client *c) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment