Skip to content

Commit 6f31abc

Browse files
authored
Ensure FrozenEngine always applies engine-level wrapper (#76100)
FrozenEngine does not always apply the engine-level DirectoryReader wrapper. Only affects combination of source-only snapshot repositories and shared_cache searchable snapshots. While it is technically a bug, it is such an exotic combination of things that it might not be even worth calling out. The fix is mostly here to ensure that future wrappers won't suffer from the same fate.
1 parent d510fa4 commit 6f31abc

File tree

3 files changed

+13
-5
lines changed

3 files changed

+13
-5
lines changed

server/src/main/java/org/elasticsearch/index/engine/ReadOnlyEngine.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public class ReadOnlyEngine extends Engine {
7676

7777
protected volatile TranslogStats translogStats;
7878
private final String commitId;
79+
private final Function<DirectoryReader, DirectoryReader> readerWrapperFunction;
7980

8081
/**
8182
* Creates a new ReadOnlyEngine. This ctor can also be used to open a read-only engine on top of an already opened
@@ -116,7 +117,8 @@ public ReadOnlyEngine(EngineConfig config, SeqNoStats seqNoStats, TranslogStats
116117
this.seqNoStats = seqNoStats;
117118
this.indexCommit = Lucene.getIndexCommit(lastCommittedSegmentInfos, directory);
118119
this.lazilyLoadSoftDeletes = lazilyLoadSoftDeletes;
119-
reader = wrapReader(open(indexCommit), readerWrapperFunction);
120+
this.readerWrapperFunction = readerWrapperFunction;
121+
reader = wrapReader(open(indexCommit));
120122
readerManager = new ElasticsearchReaderManager(reader);
121123
assert translogStats != null || obtainLock : "mutiple translogs instances should not be opened at the same time";
122124
this.translogStats = translogStats != null ? translogStats : translogStats(config, lastCommittedSegmentInfos);
@@ -192,8 +194,7 @@ public void verifyEngineBeforeIndexClosing() throws IllegalStateException {
192194
// reopened as an internal engine, which would be the path to fix the issue.
193195
}
194196

195-
protected final ElasticsearchDirectoryReader wrapReader(DirectoryReader reader,
196-
Function<DirectoryReader, DirectoryReader> readerWrapperFunction) throws IOException {
197+
protected final ElasticsearchDirectoryReader wrapReader(DirectoryReader reader) throws IOException {
197198
reader = readerWrapperFunction.apply(reader);
198199
return ElasticsearchDirectoryReader.wrap(reader, engineConfig.getShardId());
199200
}

x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/frozen/FrozenEngine.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ private synchronized ElasticsearchDirectoryReader getOrOpenReader() throws IOExc
161161
listeners.beforeRefresh();
162162
}
163163
final DirectoryReader dirReader = openDirectory(engineConfig.getStore().directory());
164-
reader = lastOpenedReader = wrapReader(dirReader, Function.identity());
164+
reader = lastOpenedReader = wrapReader(dirReader);
165165
reader.getReaderCacheHelper().addClosedListener(this::onReaderClosed);
166166
for (ReferenceManager.RefreshListener listeners : config().getInternalRefreshListener()) {
167167
listeners.afterRefresh(true);

x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/xpack/searchablesnapshots/AbstractSearchableSnapshotsRestTestCase.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
import org.elasticsearch.common.xcontent.XContentBuilder;
2222
import org.elasticsearch.common.xcontent.json.JsonXContent;
2323
import org.elasticsearch.common.xcontent.support.XContentMapValues;
24+
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
2425
import org.elasticsearch.index.query.QueryBuilder;
2526
import org.elasticsearch.index.query.QueryBuilders;
2627
import org.elasticsearch.rest.RestStatus;
2728
import org.elasticsearch.search.builder.SearchSourceBuilder;
29+
import org.elasticsearch.search.sort.SortOrder;
2830
import org.elasticsearch.test.rest.ESRestTestCase;
2931

3032
import java.io.IOException;
@@ -468,7 +470,12 @@ protected static Number count(String index) throws IOException {
468470

469471
protected static Map<String, Object> search(String index, QueryBuilder query, Boolean ignoreThrottled) throws IOException {
470472
final Request request = new Request(HttpPost.METHOD_NAME, '/' + index + "/_search");
471-
request.setJsonEntity(new SearchSourceBuilder().trackTotalHits(true).query(query).toString());
473+
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().trackTotalHits(true).query(query);
474+
if (randomBoolean()) {
475+
// ensures we can always access sequence numbers, even on source-only mounted snapshots
476+
searchSourceBuilder.sort(SeqNoFieldMapper.NAME, SortOrder.ASC);
477+
}
478+
request.setJsonEntity(searchSourceBuilder.toString());
472479
if (ignoreThrottled != null) {
473480
request.addParameter("ignore_throttled", ignoreThrottled.toString());
474481
}

0 commit comments

Comments
 (0)