summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2014-02-11 00:32:39 +0100
committerantirez <antirez@gmail.com>2014-02-11 00:39:24 +0100
commit2e3f6b0fb3bad26108885c57616b7a7312a0d8f7 (patch)
tree802fd0dcbbd3329b1a81f88be62e5d87815538f1 /src
parenta221ae5ce261dfb317583d786eb8077d6fcf2e71 (diff)
downloadredis-2e3f6b0fb3bad26108885c57616b7a7312a0d8f7.tar.gz
Cluster: on resharding upgrade version of receiving node.
The node receiving the hash slot needs to have a version that wins over the other versions in order to force the ownership of the slot. However the current code is far from perfect since a failover can happen during the manual resharding. The fix is a work in progress but the bottom line is that the new version must either be voted as usually, set by redis-trib manually after it makes sure can't be used by other nodes, or reserved configEpochs could be used for manual operations (for example odd versions could be never used by slaves and are always used by CLUSTER SETSLOT NODE).
Diffstat (limited to 'src')
-rw-r--r--src/cluster.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/cluster.c b/src/cluster.c
index 57f502c7d..452ddf579 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -3169,11 +3169,15 @@ void clusterCommand(redisClient *c) {
clusterNode *old_owner =
server.cluster->importing_slots_from[slot];
/* This slot was manually migrated, set this node configEpoch
- * at least to the value of the configEpoch of the old owner
- * so that its old replicas, or some of its old message pending
- * on the cluster bus, can't claim our slot. */
+ * to a new epoch so that the new version can be propagated
+ * by the cluster.
+ *
+ * FIXME: the new version should be agreed otherwise a race
+ * is possible if while a manual resharding is in progress
+ * the master is failed over by a slave. */
if (old_owner->configEpoch > myself->configEpoch) {
- myself->configEpoch = old_owner->configEpoch;
+ server.cluster->currentEpoch++;
+ myself->configEpoch = server.cluster->currentEpoch;
clusterDoBeforeSleep(CLUSTER_TODO_FSYNC_CONFIG);
}
server.cluster->importing_slots_from[slot] = NULL;