From 4fdde78c72ac18f51460be9ac96d1d638a969c9d Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 2 May 2016 16:41:56 +0200 Subject: [PATCH] New masters with slots are now targets of migration if others are. This fixes issue #3043. Before this fix, after a complete resharding of a master slots to other nodes, the master remains empty and the slaves migrate away to other masters with non-zero nodes. However the old master now empty, is no longer considered a target for migration, because the system has no way to tell it had slaves in the past. This fix leaves the algorithm used in the past untouched, but adds a new rule. When a new or old master which is empty and without slaves, are assigend with their first slot, if other masters in the cluster have slaves, they are automatically considered to be targets for replicas migration. --- src/cluster.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 2f00e4d1..4507d3e3 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -3439,11 +3439,45 @@ void bitmapClearBit(unsigned char *bitmap, int pos) { bitmap[byte] &= ~(1<nodes); + dictEntry *de; + int slaves = 0; + while((de = dictNext(di)) != NULL) { + clusterNode *node = dictGetVal(de); + + if (nodeIsSlave(node)) continue; + slaves += node->numslaves; + } + dictReleaseIterator(di); + return slaves != 0; +} + /* Set the slot bit and return the old value. */ int clusterNodeSetSlotBit(clusterNode *n, int slot) { int old = bitmapTestBit(n->slots,slot); bitmapSetBit(n->slots,slot); - if (!old) n->numslots++; + if (!old) { + n->numslots++; + /* When a master gets its first slot, even if it has no slaves, + * it gets flagged with MIGRATE_TO, that is, the master is a valid + * target for replicas migration, if and only if at least one of + * the other masters has slaves right now. + * + * Normally masters are valid targerts of replica migration if: + * 1. The used to have slaves (but no longer have). + * 2. They are slaves failing over a master that used to have slaves. + * + * However new masters with slots assigned are considered valid + * migration tagets if the rest of the cluster is not a slave-less. + * + * See https://github.com/antirez/redis/issues/3043 for more info. */ + if (n->numslots == 1 && clusterMastersHaveSlaves()) + n->flags |= CLUSTER_NODE_MIGRATE_TO; + } return old; }