Diskless replication: handle putting the slave online.

This commit is contained in:
antirez 2014-10-15 15:31:19 +02:00
parent 7a1e0d9898
commit 3730d118a3

View File

@ -611,6 +611,29 @@ void replconfCommand(redisClient *c) {
addReply(c,shared.ok); addReply(c,shared.ok);
} }
/* This function puts a slave in the online state, and should be called just
* after a slave received the RDB file for the initial synchronization, and
* we are finally ready to send the incremental stream of commands.
*
* It does a few things:
*
* 1) Put the slave in ONLINE state.
* 2) Make sure the writable event is re-installed, since calling the SYNC
* command disables it, so that we can accumulate output buffer without
* sending it to the slave.
* 3) Update the count of good slaves. */
void putSlaveOnline(redisClient *slave) {
slave->replstate = REDIS_REPL_ONLINE;
slave->repl_ack_time = server.unixtime;
if (aeCreateFileEvent(server.el, slave->fd, AE_WRITABLE,
sendReplyToClient, slave) == AE_ERR) {
redisLog(REDIS_WARNING,"Unable to register writable event for slave bulk transfer: %s", strerror(errno));
freeClient(slave);
return;
}
refreshGoodSlavesCount();
}
void sendBulkToSlave(aeEventLoop *el, int fd, void *privdata, int mask) { void sendBulkToSlave(aeEventLoop *el, int fd, void *privdata, int mask) {
redisClient *slave = privdata; redisClient *slave = privdata;
REDIS_NOTUSED(el); REDIS_NOTUSED(el);
@ -661,16 +684,8 @@ void sendBulkToSlave(aeEventLoop *el, int fd, void *privdata, int mask) {
close(slave->repldbfd); close(slave->repldbfd);
slave->repldbfd = -1; slave->repldbfd = -1;
aeDeleteFileEvent(server.el,slave->fd,AE_WRITABLE); aeDeleteFileEvent(server.el,slave->fd,AE_WRITABLE);
slave->replstate = REDIS_REPL_ONLINE; putSlaveOnline(slave);
slave->repl_ack_time = server.unixtime; redisLog(REDIS_NOTICE,"Synchronization with slave succeeded (disk)");
if (aeCreateFileEvent(server.el, slave->fd, AE_WRITABLE,
sendReplyToClient, slave) == AE_ERR) {
redisLog(REDIS_WARNING,"Unable to register writable event for slave bulk transfer: %s", strerror(errno));
freeClient(slave);
return;
}
refreshGoodSlavesCount();
redisLog(REDIS_NOTICE,"Synchronization with slave succeeded");
} }
} }
@ -700,6 +715,16 @@ void updateSlavesWaitingBgsave(int bgsaveerr, int type) {
} else if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_END) { } else if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_END) {
struct redis_stat buf; struct redis_stat buf;
/* If this was an RDB on disk save, we have to prepare to send
* the RDB from disk to the slave socket. Otherwise if this was
* already an RDB -> Slaves socket transfer, used in the case of
* diskless replication, our work is trivial, we can just put
* the slave online. */
if (type == REDIS_RDB_CHILD_TYPE_SOCKET) {
putSlaveOnline(slave);
redisLog(REDIS_NOTICE,
"Synchronization with slave succeeded (socket)");
} else {
if (bgsaveerr != REDIS_OK) { if (bgsaveerr != REDIS_OK) {
freeClient(slave); freeClient(slave);
redisLog(REDIS_WARNING,"SYNC failed. BGSAVE child returned an error"); redisLog(REDIS_WARNING,"SYNC failed. BGSAVE child returned an error");
@ -724,6 +749,7 @@ void updateSlavesWaitingBgsave(int bgsaveerr, int type) {
} }
} }
} }
}
if (startbgsave) { if (startbgsave) {
if (startBgsaveForReplication() != REDIS_OK) { if (startBgsaveForReplication() != REDIS_OK) {
listIter li; listIter li;