From b5ed6350a0ea444553242ef2b141161c0fc3830b Mon Sep 17 00:00:00 2001 From: Andrzej Bialecki Date: Thu, 2 Aug 2018 21:10:01 +0200 Subject: [PATCH] SOLR-12509: Fix a bug when using round-robin doc assignment. --- .../apache/solr/update/SolrIndexSplitter.java | 27 +++++++++++-------- .../solr/update/SolrIndexSplitterTest.java | 10 ++++--- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java index 75234fa77d9..334a29df3ec 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java +++ b/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java @@ -26,6 +26,7 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.index.CodecReader; import org.apache.lucene.index.FilterCodecReader; @@ -212,11 +213,14 @@ public class SolrIndexSplitter { log.info("SolrIndexSplitter: partitions=" + numPieces + " segments=" + leaves.size()); RTimerTree t; + // this tracks round-robin assignment of docs to partitions + AtomicInteger currentPartition = new AtomicInteger(); + if (splitMethod != SplitMethod.LINK) { t = timings.sub("findDocSetsPerLeaf"); for (LeafReaderContext readerContext : leaves) { assert readerContext.ordInParent == segmentDocSets.size(); // make sure we're going in order - FixedBitSet[] docSets = split(readerContext, numPieces, field, rangesArr, splitKey, hashRouter, false); + FixedBitSet[] docSets = split(readerContext, numPieces, field, rangesArr, splitKey, hashRouter, currentPartition, false); segmentDocSets.add(docSets); } t.stop(); @@ -295,7 +299,7 @@ public class SolrIndexSplitter { t.resume(); // apply deletions specific to this partition. As a side-effect on the first call this also populates // a cache of docsets to delete per leaf reader per partition, which is reused for subsequent partitions. - iw.deleteDocuments(new SplittingQuery(partitionNumber, field, rangesArr, hashRouter, splitKey, docsToDeleteCache)); + iw.deleteDocuments(new SplittingQuery(partitionNumber, field, rangesArr, hashRouter, splitKey, docsToDeleteCache, currentPartition)); t.pause(); } else { // This removes deletions but optimize might still be needed because sub-shards will have the same number of segments as the parent shard. @@ -433,15 +437,17 @@ public class SolrIndexSplitter { private final HashBasedRouter hashRouter; private final String splitKey; private final Map docsToDelete; + private final AtomicInteger currentPartition; SplittingQuery(int partition, SchemaField field, DocRouter.Range[] rangesArr, HashBasedRouter hashRouter, String splitKey, - Map docsToDelete) { + Map docsToDelete, AtomicInteger currentPartition) { this.partition = partition; this.field = field; this.rangesArr = rangesArr; this.hashRouter = hashRouter; this.splitKey = splitKey; this.docsToDelete = docsToDelete; + this.currentPartition = currentPartition; } @Override @@ -493,7 +499,7 @@ public class SolrIndexSplitter { return perPartition[partition]; } - perPartition = split(readerContext, numPieces, field, rangesArr, splitKey, hashRouter, true); + perPartition = split(readerContext, numPieces, field, rangesArr, splitKey, hashRouter, currentPartition, true); docsToDelete.put(readerContext.reader().getCoreCacheHelper().getKey(), perPartition); return perPartition[partition]; } @@ -526,7 +532,7 @@ public class SolrIndexSplitter { } static FixedBitSet[] split(LeafReaderContext readerContext, int numPieces, SchemaField field, DocRouter.Range[] rangesArr, - String splitKey, HashBasedRouter hashRouter, boolean delete) throws IOException { + String splitKey, HashBasedRouter hashRouter, AtomicInteger currentPartition, boolean delete) throws IOException { LeafReader reader = readerContext.reader(); FixedBitSet[] docSets = new FixedBitSet[numPieces]; for (int i=0; i