diff options
-rw-r--r-- | src/rdb.c | 34 | ||||
-rw-r--r-- | src/rdb.h | 1 | ||||
-rw-r--r-- | src/replication.c | 14 | ||||
-rw-r--r-- | src/server.c | 23 |
4 files changed, 49 insertions, 23 deletions
@@ -858,16 +858,14 @@ int rdbSaveInfoAuxFields(rio *rdb, int flags, rdbSaveInfo *rsi) { /* Handle saving options that generate aux fields. */ if (rsi) { - if (rsi->repl_stream_db && - rdbSaveAuxFieldStrInt(rdb,"repl-stream-db",rsi->repl_stream_db) - == -1) - { - return -1; - } + if (rdbSaveAuxFieldStrInt(rdb,"repl-stream-db",rsi->repl_stream_db) + == -1) return -1; + if (rdbSaveAuxFieldStrStr(rdb,"repl-id",server.replid) + == -1) return -1; + if (rdbSaveAuxFieldStrInt(rdb,"repl-offset",server.master_repl_offset) + == -1) return -1; } if (rdbSaveAuxFieldStrInt(rdb,"aof-preamble",aof_preamble) == -1) return -1; - if (rdbSaveAuxFieldStrStr(rdb,"repl-id",server.replid) == -1) return -1; - if (rdbSaveAuxFieldStrInt(rdb,"repl-offset",server.master_repl_offset) == -1) return -1; return 1; } @@ -2017,3 +2015,23 @@ void bgsaveCommand(client *c) { addReply(c,shared.err); } } + +/* Populate the rdbSaveInfo structure used to persist the replication + * information inside the RDB file. 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 + * information. */ +rdbSaveInfo *rdbPopulateSaveInfo(rdbSaveInfo *rsi) { + rdbSaveInfo rsi_init = RDB_SAVE_INFO_INIT; + *rsi = rsi_init; + if (server.master) { + rsi->repl_stream_db = server.master->db->id; + return rsi; + } else { + return NULL; + } +} @@ -147,5 +147,6 @@ int rdbLoadBinaryDoubleValue(rio *rdb, double *val); int rdbSaveBinaryFloatValue(rio *rdb, float val); int rdbLoadBinaryFloatValue(rio *rdb, float *val); int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi); +rdbSaveInfo *rdbPopulateSaveInfo(rdbSaveInfo *rsi); #endif diff --git a/src/replication.c b/src/replication.c index 97ce9608d..2b2673a4b 100644 --- a/src/replication.c +++ b/src/replication.c @@ -569,18 +569,12 @@ int startBgsaveForReplication(int mincapa) { serverLog(LL_NOTICE,"Starting BGSAVE for SYNC with target: %s", socket_target ? "slaves sockets" : "disk"); - rdbSaveInfo rsi = RDB_SAVE_INFO_INIT; - /* If we are saving for a chained slave (that is, if we are, - * in turn, a slave of another instance), make sure after - * loadig the RDB, our slaves select the right DB: we'll just - * send the replication stream we receive from our master, so - * no way to send SELECT commands. */ - if (server.master) rsi.repl_stream_db = server.master->db->id; - + rdbSaveInfo rsi, *rsiptr; + rsiptr = rdbPopulateSaveInfo(&rsi); if (socket_target) - retval = rdbSaveToSlavesSockets(&rsi); + retval = rdbSaveToSlavesSockets(rsiptr); else - retval = rdbSaveBackground(server.rdb_filename,&rsi); + retval = rdbSaveBackground(server.rdb_filename,rsiptr); /* If we failed to BGSAVE, remove the slaves waiting for a full * resynchorinization from the list of salves, inform them with diff --git a/src/server.c b/src/server.c index 312b95048..61291fde5 100644 --- a/src/server.c +++ b/src/server.c @@ -1092,7 +1092,9 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { { serverLog(LL_NOTICE,"%d changes in %d seconds. Saving...", sp->changes, (int)sp->seconds); - rdbSaveBackground(server.rdb_filename,NULL); + rdbSaveInfo rsi, *rsiptr; + rsiptr = rdbPopulateSaveInfo(&rsi); + rdbSaveBackground(server.rdb_filename,rsiptr); break; } } @@ -1164,7 +1166,9 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { (server.unixtime-server.lastbgsave_try > CONFIG_BGSAVE_RETRY_DELAY || server.lastbgsave_status == C_OK)) { - if (rdbSaveBackground(server.rdb_filename,NULL) == C_OK) + rdbSaveInfo rsi, *rsiptr; + rsiptr = rdbPopulateSaveInfo(&rsi); + if (rdbSaveBackground(server.rdb_filename,rsiptr) == C_OK) server.rdb_bgsave_scheduled = 0; } @@ -2546,7 +2550,9 @@ int prepareForShutdown(int flags) { if ((server.saveparamslen > 0 && !nosave) || save) { serverLog(LL_NOTICE,"Saving the final RDB snapshot before exiting."); /* Snapshotting. Perform a SYNC SAVE and exit */ - if (rdbSave(server.rdb_filename,NULL) != C_OK) { + rdbSaveInfo rsi, *rsiptr; + rsiptr = rdbPopulateSaveInfo(&rsi); + if (rdbSave(server.rdb_filename,rsiptr) != C_OK) { /* Ooops.. error saving! The best we can do is to continue * operating. Note that if there was a background saving process, * in the next cron() Redis will be notified that the background @@ -3526,13 +3532,20 @@ void loadDataFromDisk(void) { (float)(ustime()-start)/1000000); /* Restore the replication ID / offset from the RDB file. */ - if (rsi.repl_id_is_set && rsi.repl_offset != -1) { + if (server.masterhost && + rsi.repl_id_is_set && + rsi.repl_offset != -1 && + /* Note that older implementations may save a repl_stream_db + * of -1 inside the RDB file. */ + rsi.repl_stream_db != -1) + { memcpy(server.replid,rsi.repl_id,sizeof(server.replid)); server.master_repl_offset = rsi.repl_offset; /* If we are a slave, create a cached master from this * information, in order to allow partial resynchronizations * with masters. */ - if (server.masterhost) replicationCacheMasterUsingMyself(); + replicationCacheMasterUsingMyself(); + selectDb(server.cached_master,rsi.repl_stream_db); } } else if (errno != ENOENT) { serverLog(LL_WARNING,"Fatal error loading the DB: %s. Exiting.",strerror(errno)); |