mirror of
https://github.com/fluencelabs/redis
synced 2025-03-21 01:50:50 +00:00
Diskless replication: parent-child pipe and a few TODOs.
This commit is contained in:
parent
75f0cd6520
commit
1cd0d26c63
37
src/rdb.c
37
src/rdb.c
@ -1274,7 +1274,13 @@ void backgroundSaveDoneHandlerDisk(int exitcode, int bysignal) {
|
|||||||
|
|
||||||
/* A background saving child (BGSAVE) terminated its work. Handle this.
|
/* A background saving child (BGSAVE) terminated its work. Handle this.
|
||||||
* This function covers the case of RDB -> Salves socket transfers for
|
* This function covers the case of RDB -> Salves socket transfers for
|
||||||
* diskless replication. */
|
* diskless replication.
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* 1) Read from the pipe the set of IDs which are fine. This should be
|
||||||
|
* just an uint32_t with the len, and N pid_t elements.
|
||||||
|
* 2) Close all the slaves in state REDIS_REPL_WAIT_BGSAVE_END but are
|
||||||
|
* not reported as "transfer ok" by the child. */
|
||||||
void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
|
void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
|
||||||
if (!bysignal && exitcode == 0) {
|
if (!bysignal && exitcode == 0) {
|
||||||
redisLog(REDIS_NOTICE,
|
redisLog(REDIS_NOTICE,
|
||||||
@ -1288,8 +1294,18 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
|
|||||||
server.rdb_child_pid = -1;
|
server.rdb_child_pid = -1;
|
||||||
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_NONE;
|
server.rdb_child_type = REDIS_RDB_CHILD_TYPE_NONE;
|
||||||
server.rdb_save_time_start = -1;
|
server.rdb_save_time_start = -1;
|
||||||
/* Possibly there are slaves waiting for a BGSAVE in order to be served
|
/* Read the set of slave client IDs that currently received the full
|
||||||
* (the first stage of SYNC is a bulk transfer of dump.rdb) */
|
* RDB payload, closing all the slaves which are not among the ones
|
||||||
|
* listed. */
|
||||||
|
|
||||||
|
/* TODO ... */
|
||||||
|
|
||||||
|
/* Close the pipe FDs. */
|
||||||
|
|
||||||
|
/* TODO ... */
|
||||||
|
|
||||||
|
/* We can continue the replication process with all the slaves that
|
||||||
|
* correctly received the full payload. */
|
||||||
updateSlavesWaitingBgsave((!bysignal && exitcode == 0) ? REDIS_OK : REDIS_ERR, REDIS_RDB_CHILD_TYPE_SOCKET);
|
updateSlavesWaitingBgsave((!bysignal && exitcode == 0) ? REDIS_OK : REDIS_ERR, REDIS_RDB_CHILD_TYPE_SOCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1317,9 +1333,19 @@ int rdbSaveToSlavesSockets(void) {
|
|||||||
listIter li;
|
listIter li;
|
||||||
pid_t childpid;
|
pid_t childpid;
|
||||||
long long start;
|
long long start;
|
||||||
|
int pipefds[2];
|
||||||
|
|
||||||
if (server.rdb_child_pid != -1) return REDIS_ERR;
|
if (server.rdb_child_pid != -1) return REDIS_ERR;
|
||||||
|
|
||||||
|
/* Before to fork, create a pipe that will be used in order to
|
||||||
|
* send back to the parent the IDs of the slaves that successfully
|
||||||
|
* received all the writes. */
|
||||||
|
if (pipe(pipefds) == -1) return REDIS_ERR;
|
||||||
|
server.rdb_pipe_read_result_from_child = pipefds[0];
|
||||||
|
server.rdb_pipe_write_result_to_parent = pipefds[1];
|
||||||
|
|
||||||
|
/* Collect the file descriptors of the slaves we want to transfer
|
||||||
|
* the RDB to, which are i WAIT_BGSAVE_START state. */
|
||||||
fds = zmalloc(sizeof(int)*listLength(server.slaves));
|
fds = zmalloc(sizeof(int)*listLength(server.slaves));
|
||||||
numfds = 0;
|
numfds = 0;
|
||||||
|
|
||||||
@ -1333,7 +1359,7 @@ int rdbSaveToSlavesSockets(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fork ... */
|
/* Create the child process. */
|
||||||
start = ustime();
|
start = ustime();
|
||||||
if ((childpid = fork()) == 0) {
|
if ((childpid = fork()) == 0) {
|
||||||
/* Child */
|
/* Child */
|
||||||
@ -1365,6 +1391,9 @@ int rdbSaveToSlavesSockets(void) {
|
|||||||
if (childpid == -1) {
|
if (childpid == -1) {
|
||||||
redisLog(REDIS_WARNING,"Can't save in background: fork: %s",
|
redisLog(REDIS_WARNING,"Can't save in background: fork: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
zfree(fds);
|
||||||
|
close(pipefds[0]);
|
||||||
|
close(pipefds[1]);
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
redisLog(REDIS_NOTICE,"Background RDB transfer started by pid %d",childpid);
|
redisLog(REDIS_NOTICE,"Background RDB transfer started by pid %d",childpid);
|
||||||
|
@ -775,6 +775,8 @@ struct redisServer {
|
|||||||
int rdb_child_type; /* Type of save by active child. */
|
int rdb_child_type; /* Type of save by active child. */
|
||||||
int lastbgsave_status; /* REDIS_OK or REDIS_ERR */
|
int lastbgsave_status; /* REDIS_OK or REDIS_ERR */
|
||||||
int stop_writes_on_bgsave_err; /* Don't allow writes if can't BGSAVE */
|
int stop_writes_on_bgsave_err; /* Don't allow writes if can't BGSAVE */
|
||||||
|
int rdb_pipe_write_result_to_parent; /* RDB pipes used to return the state */
|
||||||
|
int rdb_pipe_read_result_from_child; /* of each slave in diskless SYNC. */
|
||||||
/* Propagation of commands in AOF / replication */
|
/* Propagation of commands in AOF / replication */
|
||||||
redisOpArray also_propagate; /* Additional command to propagate. */
|
redisOpArray also_propagate; /* Additional command to propagate. */
|
||||||
/* Logging */
|
/* Logging */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user