diff --git a/src/db.c b/src/db.c index 7d1504d30..71c642d00 100644 --- a/src/db.c +++ b/src/db.c @@ -416,7 +416,9 @@ void flushallCommand(client *c) { /* Normally rdbSave() will reset dirty, but we don't want this here * as otherwise FLUSHALL will not be replicated nor put into the AOF. */ int saved_dirty = server.dirty; - rdbSave(server.rdb_filename,NULL); + rdbSaveInfo rsi, *rsiptr; + rsiptr = rdbPopulateSaveInfo(&rsi); + rdbSave(server.rdb_filename,rsiptr); server.dirty = saved_dirty; } server.dirty++; diff --git a/src/debug.c b/src/debug.c index d6e12ec2a..5c3fd3471 100644 --- a/src/debug.c +++ b/src/debug.c @@ -335,7 +335,9 @@ void debugCommand(client *c) { if (c->argc >= 3) c->argv[2] = tryObjectEncoding(c->argv[2]); serverAssertWithInfo(c,c->argv[0],1 == 2); } else if (!strcasecmp(c->argv[1]->ptr,"reload")) { - if (rdbSave(server.rdb_filename,NULL) != C_OK) { + rdbSaveInfo rsi, *rsiptr; + rsiptr = rdbPopulateSaveInfo(&rsi); + if (rdbSave(server.rdb_filename,rsiptr) != C_OK) { addReply(c,shared.err); return; } diff --git a/src/rdb.c b/src/rdb.c index 9c2acf7ba..c83a05a32 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -1975,7 +1975,9 @@ void saveCommand(client *c) { addReplyError(c,"Background save already in progress"); return; } - if (rdbSave(server.rdb_filename,NULL) == C_OK) { + rdbSaveInfo rsi, *rsiptr; + rsiptr = rdbPopulateSaveInfo(&rsi); + if (rdbSave(server.rdb_filename,rsiptr) == C_OK) { addReply(c,shared.ok); } else { addReply(c,shared.err); @@ -2017,21 +2019,33 @@ void bgsaveCommand(client *c) { } /* Populate the rdbSaveInfo structure used to persist the replication - * information inside the RDB file. Currently the structure explicitly + * information inside the RDB file. + * For master, if server.repl_backlog is not NULL, fill rdbSaveInfo with + * server.slaveseldb, otherwise just use init -1. + * Don't worry, master will send SELECT command to replication stream, + * because if server.repl_backlog is NULL, that will trigger full synchronization, + * function replicationSetupSlaveForFullResync() sets server.slaveseldb be -1, + * then replicationFeedSlaves() will send SELECT command when server.slaveseldb is -1. + * For slave, currently the structure explicitly * contains just the currently selected DB from the master stream, however * if the rdbSave*() family functions receive a NULL rsi structure also * the Replication ID/offset is not saved. The function popultes 'rsi' * that is normally stack-allocated in the caller, returns the populated * pointer if the instance has a valid master client, otherwise NULL - * is returned, and the RDB savign wil not persist any replication related + * is returned, and the RDB saving will not persist any replication related * information. */ rdbSaveInfo *rdbPopulateSaveInfo(rdbSaveInfo *rsi) { rdbSaveInfo rsi_init = RDB_SAVE_INFO_INIT; *rsi = rsi_init; + if (!server.masterhost) { + if (server.repl_backlog) rsi->repl_stream_db = server.slaveseldb; + return rsi; + } if (server.master) { rsi->repl_stream_db = server.master->db->id; return rsi; } else { + serverLog(LL_WARNING,"As a slave there is no valid master, can not persist replication information"); return NULL; } } diff --git a/src/replication.c b/src/replication.c index 2b2673a4b..4358d63e6 100644 --- a/src/replication.c +++ b/src/replication.c @@ -571,10 +571,16 @@ int startBgsaveForReplication(int mincapa) { rdbSaveInfo rsi, *rsiptr; rsiptr = rdbPopulateSaveInfo(&rsi); - if (socket_target) - retval = rdbSaveToSlavesSockets(rsiptr); - else - retval = rdbSaveBackground(server.rdb_filename,rsiptr); + /* Only do rdbSave* when rsiptr is not NULL, + * otherwise slave will miss repl-stream-db. */ + if (rsiptr) { + if (socket_target) + retval = rdbSaveToSlavesSockets(rsiptr); + else + retval = rdbSaveBackground(server.rdb_filename,rsiptr); + } else { + retval = C_ERR; + } /* If we failed to BGSAVE, remove the slaves waiting for a full * resynchorinization from the list of salves, inform them with