diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 6128986d48b..98fb204ac55 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -71,6 +71,8 @@ Other Changes java.time.DateTimeFormatter instead of Joda time (see upgrade notes). "Lenient" is enabled. Removed Joda Time dependency. (David Smiley, Bar Rotstein) +* SOLR-12805: Store previous term (generation) of replica when start recovery process (Cao Manh Dat) + ================== 7.6.0 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. 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 99df2a205ce..bcbb347f328 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkShardTerms.java @@ -588,12 +588,16 @@ public class ZkShardTerms implements AutoCloseable{ */ Terms startRecovering(String coreNodeName) { long maxTerm = getMaxTerm(); - if (values.get(coreNodeName) == maxTerm && values.getOrDefault(coreNodeName+"_recovering", -1L) == maxTerm) + if (values.get(coreNodeName) == maxTerm) return null; HashMap newValues = new HashMap<>(values); + if (!newValues.containsKey(coreNodeName+"_recovering")) { + long currentTerm = newValues.getOrDefault(coreNodeName, 0L); + // by keeping old term, we will have more information in leader election + newValues.put(coreNodeName+"_recovering", currentTerm); + } newValues.put(coreNodeName, maxTerm); - newValues.put(coreNodeName+"_recovering", maxTerm); return new Terms(newValues, version); } 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 201de2662fb..1c1b1d2233a 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ZkShardTermsTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ZkShardTermsTest.java @@ -83,16 +83,19 @@ public class ZkShardTermsTest extends SolrCloudTestCase { // List all possible orders of ensureTermIsHigher, startRecovering, doneRecovering zkShardTerms.registerTerm("replica1"); zkShardTerms.registerTerm("replica2"); + + // normal case when leader start lir process zkShardTerms.ensureTermsIsHigher("replica1", Collections.singleton("replica2")); zkShardTerms.startRecovering("replica2"); assertEquals(zkShardTerms.getTerm("replica2"), 1); - assertEquals(zkShardTerms.getTerm("replica2_recovering"), 1); + assertEquals(zkShardTerms.getTerm("replica2_recovering"), 0); zkShardTerms.doneRecovering("replica2"); assertEquals(zkShardTerms.getTerm("replica1"), 1); assertEquals(zkShardTerms.getTerm("replica2"), 1); assertEquals(zkShardTerms.getTerm("replica2_recovering"), -1); + // stack of lir processes zkShardTerms.ensureTermsIsHigher("replica1", Collections.singleton("replica2")); assertEquals(zkShardTerms.getTerm("replica1"), 2); assertEquals(zkShardTerms.getTerm("replica2"), 1); @@ -100,16 +103,17 @@ public class ZkShardTermsTest extends SolrCloudTestCase { zkShardTerms.startRecovering("replica2"); assertEquals(zkShardTerms.getTerm("replica2"), 2); - assertEquals(zkShardTerms.getTerm("replica2_recovering"), 2); + assertEquals(zkShardTerms.getTerm("replica2_recovering"), 1); zkShardTerms.ensureTermsIsHigher("replica1", Collections.singleton("replica2")); assertEquals(zkShardTerms.getTerm("replica1"), 3); assertEquals(zkShardTerms.getTerm("replica2"), 2); - assertEquals(zkShardTerms.getTerm("replica2_recovering"), 2); - zkShardTerms.doneRecovering("replica2"); + assertEquals(zkShardTerms.getTerm("replica2_recovering"), 1); + zkShardTerms.doneRecovering("replica2"); assertEquals(zkShardTerms.getTerm("replica2"), 2); assertEquals(zkShardTerms.getTerm("replica2_recovering"), -1); + zkShardTerms.startRecovering("replica2"); zkShardTerms.doneRecovering("replica2"); @@ -119,7 +123,7 @@ public class ZkShardTermsTest extends SolrCloudTestCase { zkShardTerms.startRecovering("replica2"); assertEquals(zkShardTerms.getTerm("replica1"), 5); assertEquals(zkShardTerms.getTerm("replica2"), 5); - assertEquals(zkShardTerms.getTerm("replica2_recovering"), 5); + assertEquals(zkShardTerms.getTerm("replica2_recovering"), 3); zkShardTerms.doneRecovering("replica2"); assertEquals(zkShardTerms.getTerm("replica2_recovering"), -1);