Skip to content

Commit 9c2d1e6

Browse files
authored
Fix file reading in ccr restore service (#38117) (#38143)
Currently we use the raw byte array length when calling the IndexInput read call to determine how many bytes we want to read. However, due to how BigArrays works, the array length might be longer than the reference length. This commit fixes the issue and uses the BytesRef length when calling read. Additionally, it expands the index follow test to index many more documents. These documents should potentially lead to large enough segment files to trigger scenarios where this fix matters.
1 parent 7077cb3 commit 9c2d1e6

File tree

3 files changed

+26
-34
lines changed

3 files changed

+26
-34
lines changed

x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRestoreSourceService.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,7 @@ private long readFileBytes(String fileName, BytesReference reference) throws IOE
235235
BytesRefIterator refIterator = reference.iterator();
236236
BytesRef ref;
237237
while ((ref = refIterator.next()) != null) {
238-
byte[] refBytes = ref.bytes;
239-
indexInput.readBytes(refBytes, 0, refBytes.length);
238+
indexInput.readBytes(ref.bytes, ref.offset, ref.length);
240239
}
241240

242241
long offsetAfterRead = indexInput.getFilePointer();

x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/CcrIntegTestCase.java

-22
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
import org.elasticsearch.transport.TransportService;
6969
import org.elasticsearch.xpack.ccr.CcrSettings;
7070
import org.elasticsearch.xpack.ccr.LocalStateCcr;
71-
import org.elasticsearch.xpack.ccr.index.engine.FollowingEngine;
7271
import org.elasticsearch.xpack.core.XPackSettings;
7372
import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata;
7473
import org.elasticsearch.xpack.core.ccr.ShardFollowNodeTaskStatus;
@@ -554,27 +553,6 @@ protected void assertMaxSeqNoOfUpdatesIsTransferred(Index leaderIndex, Index fol
554553
});
555554
}
556555

557-
protected void assertTotalNumberOfOptimizedIndexing(Index followerIndex, int numberOfShards, long expectedTotal) throws Exception {
558-
assertBusy(() -> {
559-
long[] numOfOptimizedOps = new long[numberOfShards];
560-
for (int shardId = 0; shardId < numberOfShards; shardId++) {
561-
for (String node : getFollowerCluster().nodesInclude(followerIndex.getName())) {
562-
IndicesService indicesService = getFollowerCluster().getInstance(IndicesService.class, node);
563-
IndexShard shard = indicesService.getShardOrNull(new ShardId(followerIndex, shardId));
564-
if (shard != null && shard.routingEntry().primary()) {
565-
try {
566-
FollowingEngine engine = ((FollowingEngine) IndexShardTestCase.getEngine(shard));
567-
numOfOptimizedOps[shardId] = engine.getNumberOfOptimizedIndexing();
568-
} catch (AlreadyClosedException e) {
569-
throw new AssertionError(e); // causes assertBusy to retry
570-
}
571-
}
572-
}
573-
}
574-
assertThat(Arrays.stream(numOfOptimizedOps).sum(), equalTo(expectedTotal));
575-
});
576-
}
577-
578556
static void removeCCRRelatedMetadataFromClusterState(ClusterService clusterService) throws Exception {
579557
CountDownLatch latch = new CountDownLatch(1);
580558
clusterService.submitStateUpdateTask("remove-ccr-related-metadata", new ClusterStateUpdateTask() {

x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/IndexFollowingIT.java

+25-10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.action.admin.indices.stats.ShardStats;
2727
import org.elasticsearch.action.bulk.BulkProcessor;
2828
import org.elasticsearch.action.bulk.BulkRequest;
29+
import org.elasticsearch.action.bulk.BulkRequestBuilder;
2930
import org.elasticsearch.action.bulk.BulkResponse;
3031
import org.elasticsearch.action.get.GetResponse;
3132
import org.elasticsearch.action.index.IndexRequest;
@@ -101,9 +102,30 @@ public void testFollowIndex() throws Exception {
101102
assertAcked(leaderClient().admin().indices().prepareCreate("index1").setSource(leaderIndexSettings, XContentType.JSON));
102103
ensureLeaderYellow("index1");
103104

104-
final int firstBatchNumDocs = randomIntBetween(2, 64);
105+
final int firstBatchNumDocs;
106+
// Sometimes we want to index a lot of documents to ensure that the recovery works with larger files
107+
if (rarely()) {
108+
firstBatchNumDocs = randomIntBetween(1800, 2000);
109+
} else {
110+
firstBatchNumDocs = randomIntBetween(10, 64);
111+
}
112+
final int flushPoint = (int) (firstBatchNumDocs * 0.75);
113+
105114
logger.info("Indexing [{}] docs as first batch", firstBatchNumDocs);
106-
for (int i = 0; i < firstBatchNumDocs; i++) {
115+
BulkRequestBuilder bulkRequestBuilder = leaderClient().prepareBulk();
116+
for (int i = 0; i < flushPoint; i++) {
117+
final String source = String.format(Locale.ROOT, "{\"f\":%d}", i);
118+
IndexRequest indexRequest = new IndexRequest("index1", "doc", Integer.toString(i))
119+
.source(source, XContentType.JSON)
120+
.timeout(TimeValue.timeValueSeconds(1));
121+
bulkRequestBuilder.add(indexRequest);
122+
}
123+
bulkRequestBuilder.get();
124+
125+
leaderClient().admin().indices().prepareFlush("index1").setWaitIfOngoing(true).get();
126+
127+
// Index some docs after the flush that might be recovered in the normal index following operations
128+
for (int i = flushPoint; i < firstBatchNumDocs; i++) {
107129
final String source = String.format(Locale.ROOT, "{\"f\":%d}", i);
108130
leaderClient().prepareIndex("index1", "doc", Integer.toString(i)).setSource(source, XContentType.JSON).get();
109131
}
@@ -147,7 +169,7 @@ public void testFollowIndex() throws Exception {
147169
for (int i = 0; i < firstBatchNumDocs; i++) {
148170
assertBusy(assertExpectedDocumentRunnable(i));
149171
}
150-
assertTotalNumberOfOptimizedIndexing(resolveFollowerIndex("index2"), numberOfPrimaryShards, firstBatchNumDocs);
172+
151173
pauseFollow("index2");
152174
followerClient().execute(ResumeFollowAction.INSTANCE, followRequest.getFollowRequest()).get();
153175
final int secondBatchNumDocs = randomIntBetween(2, 64);
@@ -172,8 +194,6 @@ public void testFollowIndex() throws Exception {
172194
for (int i = firstBatchNumDocs; i < firstBatchNumDocs + secondBatchNumDocs; i++) {
173195
assertBusy(assertExpectedDocumentRunnable(i));
174196
}
175-
assertTotalNumberOfOptimizedIndexing(resolveFollowerIndex("index2"), numberOfPrimaryShards,
176-
firstBatchNumDocs + secondBatchNumDocs);
177197
pauseFollow("index2");
178198
assertMaxSeqNoOfUpdatesIsTransferred(resolveLeaderIndex("index1"), resolveFollowerIndex("index2"), numberOfPrimaryShards);
179199
}
@@ -287,7 +307,6 @@ public void testFollowIndexWithoutWaitForComplete() throws Exception {
287307
for (int i = 0; i < firstBatchNumDocs; i++) {
288308
assertBusy(assertExpectedDocumentRunnable(i));
289309
}
290-
assertTotalNumberOfOptimizedIndexing(resolveFollowerIndex("index2"), numberOfPrimaryShards, firstBatchNumDocs);
291310
pauseFollow("index2");
292311
}
293312

@@ -431,8 +450,6 @@ public void afterBulk(long executionId, BulkRequest request, Throwable failure)
431450
assertIndexFullyReplicatedToFollower("index1", "index2");
432451
pauseFollow("index2");
433452
leaderClient().admin().indices().prepareRefresh("index1").get();
434-
assertTotalNumberOfOptimizedIndexing(resolveFollowerIndex("index2"), numberOfShards,
435-
leaderClient().prepareSearch("index1").get().getHits().totalHits);
436453
assertMaxSeqNoOfUpdatesIsTransferred(resolveLeaderIndex("index1"), resolveFollowerIndex("index2"), numberOfShards);
437454
}
438455

@@ -474,7 +491,6 @@ public void testFollowIndexWithNestedField() throws Exception {
474491
}
475492
pauseFollow("index2");
476493
assertMaxSeqNoOfUpdatesIsTransferred(resolveLeaderIndex("index1"), resolveFollowerIndex("index2"), 1);
477-
assertTotalNumberOfOptimizedIndexing(resolveFollowerIndex("index2"), 1, numDocs);
478494
}
479495

480496
public void testUnfollowNonExistingIndex() {
@@ -537,7 +553,6 @@ public void testFollowIndexMaxOperationSizeInBytes() throws Exception {
537553
}
538554
pauseFollow("index2");
539555
assertMaxSeqNoOfUpdatesIsTransferred(resolveLeaderIndex("index1"), resolveFollowerIndex("index2"), 1);
540-
assertTotalNumberOfOptimizedIndexing(resolveFollowerIndex("index2"), 1, numDocs);
541556
}
542557

543558
public void testAttemptToChangeCcrFollowingIndexSetting() throws Exception {

0 commit comments

Comments
 (0)