Skip to content

Commit acf84b6

Browse files
committed
Do not wrap soft-deletes reader for segment stats (#51331)
IndexWriter might not filter out fully deleted segments if retention leases exist or the number of the retaining operations is non-zero. SoftDeletesDirectoryReaderWrapper, however, always filters out fully deleted segments. This change uses the original directory reader when calculating segment stats instead. Relates #51192 Closes #51303
1 parent 4e8ab43 commit acf84b6

File tree

3 files changed

+14
-9
lines changed

3 files changed

+14
-9
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public NoOpEngine(EngineConfig config) {
5454
super(config, null, null, true, Function.identity());
5555
this.stats = new SegmentsStats();
5656
Directory directory = store.directory();
57-
try (DirectoryReader reader = openDirectory(directory, config.getIndexSettings())) {
57+
// Do not wrap soft-deletes reader when calculating segment stats as the wrapper might filter out fully deleted segments.
58+
try (DirectoryReader reader = openDirectory(directory, false)) {
5859
for (LeafReaderContext ctx : reader.getContext().leaves()) {
5960
SegmentReader segmentReader = Lucene.segmentReader(ctx.reader());
6061
fillSegmentStats(segmentReader, true, stats);

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader;
3434
import org.elasticsearch.common.util.concurrent.ReleasableLock;
3535
import org.elasticsearch.core.internal.io.IOUtils;
36-
import org.elasticsearch.index.IndexSettings;
3736
import org.elasticsearch.index.mapper.MapperService;
3837
import org.elasticsearch.index.seqno.SeqNoStats;
3938
import org.elasticsearch.index.seqno.SequenceNumbers;
@@ -536,9 +535,9 @@ public void advanceMaxSeqNoOfUpdatesOrDeletes(long maxSeqNoOfUpdatesOnPrimary) {
536535
maxSeqNoOfUpdatesOnPrimary + ">" + getMaxSeqNoOfUpdatesOrDeletes();
537536
}
538537

539-
protected DirectoryReader openDirectory(Directory dir, IndexSettings indexSettings) throws IOException {
540-
final DirectoryReader reader = DirectoryReader.open(dir, OFF_HEAP_READER_ATTRIBUTES);
541-
if (indexSettings.isSoftDeleteEnabled()) {
538+
protected static DirectoryReader openDirectory(Directory directory, boolean wrapSoftDeletes) throws IOException {
539+
final DirectoryReader reader = DirectoryReader.open(directory, OFF_HEAP_READER_ATTRIBUTES);
540+
if (wrapSoftDeletes) {
542541
return new SoftDeletesDirectoryReaderWrapper(reader, Lucene.SOFT_DELETES_FIELD);
543542
} else {
544543
return reader;

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.lucene.index.PointValues;
2222
import org.apache.lucene.index.SegmentCommitInfo;
2323
import org.apache.lucene.index.SegmentReader;
24+
import org.apache.lucene.index.SoftDeletesDirectoryReaderWrapper;
2425
import org.apache.lucene.index.SortedDocValues;
2526
import org.apache.lucene.index.SortedNumericDocValues;
2627
import org.apache.lucene.index.SortedSetDocValues;
@@ -77,16 +78,19 @@ public FrozenEngine(EngineConfig config) {
7778

7879
boolean success = false;
7980
Directory directory = store.directory();
80-
try (DirectoryReader reader = openDirectory(directory, config.getIndexSettings())) {
81-
canMatchReader = ElasticsearchDirectoryReader.wrap(new RewriteCachingDirectoryReader(directory, reader.leaves()),
82-
config.getShardId());
81+
// Do not wrap soft-deletes reader when calculating segment stats as the wrapper might filter out fully deleted segments.
82+
try (DirectoryReader reader = openDirectory(directory, false)) {
8383
// we record the segment stats here - that's what the reader needs when it's open and it give the user
8484
// an idea of what it can save when it's closed
8585
this.stats = new SegmentsStats();
8686
for (LeafReaderContext ctx : reader.getContext().leaves()) {
8787
SegmentReader segmentReader = Lucene.segmentReader(ctx.reader());
8888
fillSegmentStats(segmentReader, true, stats);
8989
}
90+
final DirectoryReader wrappedReader = config.getIndexSettings().isSoftDeleteEnabled() ?
91+
new SoftDeletesDirectoryReaderWrapper(reader, Lucene.SOFT_DELETES_FIELD) : reader;
92+
canMatchReader = ElasticsearchDirectoryReader.wrap(
93+
new RewriteCachingDirectoryReader(directory, wrappedReader.leaves()), config.getShardId());
9094
success = true;
9195
} catch (IOException e) {
9296
throw new UncheckedIOException(e);
@@ -167,7 +171,8 @@ private synchronized ElasticsearchDirectoryReader getOrOpenReader() throws IOExc
167171
for (ReferenceManager.RefreshListener listeners : config ().getInternalRefreshListener()) {
168172
listeners.beforeRefresh();
169173
}
170-
final DirectoryReader dirReader = openDirectory(engineConfig.getStore().directory(), engineConfig.getIndexSettings());
174+
final DirectoryReader dirReader = openDirectory(engineConfig.getStore().directory(),
175+
engineConfig.getIndexSettings().isSoftDeleteEnabled());
171176
reader = lastOpenedReader = wrapReader(dirReader, Function.identity());
172177
processReader(reader);
173178
reader.getReaderCacheHelper().addClosedListener(this::onReaderClosed);

0 commit comments

Comments
 (0)