diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java b/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java index 50b424c083f..ca79982b1ef 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java @@ -194,7 +194,7 @@ public class ZkShardTerms implements AutoCloseable{ } /** - * Set a replica's term equals to leader's term. + * Set a replica's term equals to leader's term, and remove recovering flag of a replica. * This call should only be used by {@link org.apache.solr.common.params.CollectionParams.CollectionAction#FORCELEADER} * @param coreNodeName of the replica */ @@ -554,6 +554,7 @@ public class ZkShardTerms implements AutoCloseable{ HashMap newValues = new HashMap<>(values); newValues.put(coreNodeName, maxTerm); + newValues.remove(coreNodeName+"_recovering"); return new Terms(newValues, version); } diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java index f4855ebeeee..13f0f98f3cd 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java @@ -1148,16 +1148,10 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission .noneMatch(rep -> zkShardTerms.registered(rep.getName()) && zkShardTerms.canBecomeLeader(rep.getName())); // we won't increase replica's terms if exist a live replica with term equals to leader if (shouldIncreaseReplicaTerms) { - OptionalLong optionalMaxTerm = liveReplicas.stream() + //TODO only increase terms of replicas less out-of-sync + liveReplicas.stream() .filter(rep -> zkShardTerms.registered(rep.getName())) - .mapToLong(rep -> zkShardTerms.getTerm(rep.getName())) - .max(); - // increase terms of replicas less out-of-sync - if (optionalMaxTerm.isPresent()) { - liveReplicas.stream() - .filter(rep -> zkShardTerms.getTerm(rep.getName()) == optionalMaxTerm.getAsLong()) - .forEach(rep -> zkShardTerms.setTermEqualsToLeader(rep.getName())); - } + .forEach(rep -> zkShardTerms.setTermEqualsToLeader(rep.getName())); } // Wait till we have an active leader diff --git a/solr/core/src/test/org/apache/solr/cloud/ZkShardTermsTest.java b/solr/core/src/test/org/apache/solr/cloud/ZkShardTermsTest.java index d557b2915ee..c7f1cdb229c 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ZkShardTermsTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ZkShardTermsTest.java @@ -229,6 +229,25 @@ public class ZkShardTermsTest extends SolrCloudTestCase { replicaTerms.close(); } + public void testSetTermEqualsToLeader() throws InterruptedException { + String collection = "setTermEqualsToLeader"; + ZkShardTerms leaderTerms = new ZkShardTerms(collection, "shard1", cluster.getZkClient()); + ZkShardTerms replicaTerms = new ZkShardTerms(collection, "shard1", cluster.getZkClient()); + leaderTerms.registerTerm("leader"); + replicaTerms.registerTerm("replica"); + + leaderTerms.ensureTermsIsHigher("leader", Collections.singleton("replica")); + waitFor(false, () -> replicaTerms.canBecomeLeader("replica")); + waitFor(true, () -> leaderTerms.skipSendingUpdatesTo("replica")); + + replicaTerms.setTermEqualsToLeader("replica"); + waitFor(true, () -> replicaTerms.canBecomeLeader("replica")); + waitFor(false, () -> leaderTerms.skipSendingUpdatesTo("replica")); + + leaderTerms.close(); + replicaTerms.close(); + } + private void waitFor(T expected, Supplier supplier) throws InterruptedException { TimeOut timeOut = new TimeOut(10, TimeUnit.SECONDS, new TimeSource.CurrentTimeSource()); while (!timeOut.hasTimedOut()) {