summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2017-09-20 13:47:42 +0800
committerantirez <antirez@gmail.com>2017-09-20 11:18:10 +0200
commitb541ccef25d20749c739b858ef8694512b7f3bce (patch)
treee99ef1b6889ce2b4f2f9d4784a777e26bc2439a1
parentc1c99e9f4e19b3c68d810a51449b34c2261e24c9 (diff)
downloadredis-b541ccef25d20749c739b858ef8694512b7f3bce.tar.gz
PSYNC2: make persisiting replication info more solid
This commit is a reinforcement of commit c1c99e9. 1. Replication information can be stored when the RDB file is generated by a mater using server.slaveseldb when server.repl_backlog is not NULL, or set repl_stream_db be -1. That's safe, because NULL server.repl_backlog will trigger full synchronization, then master will send SELECT command to replicaiton stream. 2. Only do rdbSave* when rsiptr is not NULL, if we do rdbSave* without rdbSaveInfo, slave will miss repl-stream-db. 3. Save the replication informations also in the case of SAVE command, FLUSHALL command and DEBUG reload.
-rw-r--r--src/db.c4
-rw-r--r--src/debug.c4
-rw-r--r--src/rdb.c20
-rw-r--r--src/replication.c14
4 files changed, 33 insertions, 9 deletions
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