Skip to content

Commit a747535

Browse files
committed
Skip indexing points for seq_no in tsdb and logsdb
1 parent 6052c5b commit a747535

24 files changed

+190
-77
lines changed

server/src/main/java/org/elasticsearch/index/IndexSettings.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.elasticsearch.core.TimeValue;
2929
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
3030
import org.elasticsearch.index.mapper.Mapper;
31+
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
3132
import org.elasticsearch.index.mapper.SourceFieldMapper;
3233
import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper;
3334
import org.elasticsearch.index.translog.Translog;
@@ -829,6 +830,26 @@ private static String getIgnoreAboveDefaultValue(final Settings settings) {
829830
}
830831
}
831832

833+
// used in tests only
834+
public static final Setting<SeqNoFieldMapper.SeqNoIndexOptions> SEQ_NO_INDEX_OPTIONS_SETTING = Setting.enumSetting(
835+
SeqNoFieldMapper.SeqNoIndexOptions.class,
836+
IndexSettings::defaultSeqNoIndexOptions,
837+
"index.seq_no.index_options",
838+
value -> {},
839+
Property.IndexScope,
840+
Property.InternalIndex
841+
);
842+
843+
private static String defaultSeqNoIndexOptions(final Settings settings) {
844+
final IndexMode indexMode = IndexSettings.MODE.get(settings);
845+
if ((indexMode == IndexMode.LOGSDB || indexMode == IndexMode.TIME_SERIES)
846+
&& IndexMetadata.SETTING_INDEX_VERSION_CREATED.get(settings).onOrAfter(IndexVersions.SEQ_NO_WITHOUT_POINTS)) {
847+
return SeqNoFieldMapper.SeqNoIndexOptions.DOC_VALUES_ONLY.name();
848+
} else {
849+
return SeqNoFieldMapper.SeqNoIndexOptions.POINTS_AND_DOC_VALUES.name();
850+
}
851+
}
852+
832853
private final Index index;
833854
private final IndexVersion version;
834855
private final Logger logger;
@@ -933,6 +954,7 @@ private void setRetentionLeaseMillis(final TimeValue retentionLease) {
933954
private volatile int maxRegexLength;
934955

935956
private final IndexRouting indexRouting;
957+
private final SeqNoFieldMapper.SeqNoIndexOptions seqNoIndexOptions;
936958

937959
/**
938960
* The default mode for storing source, for all mappers not overriding this setting.
@@ -1099,6 +1121,7 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
10991121
recoverySourceSyntheticEnabled = DiscoveryNode.isStateless(nodeSettings) == false
11001122
&& scopedSettings.get(RECOVERY_USE_SYNTHETIC_SOURCE_SETTING);
11011123
useDocValuesSkipper = DOC_VALUES_SKIPPER && scopedSettings.get(USE_DOC_VALUES_SKIPPER);
1124+
seqNoIndexOptions = SEQ_NO_INDEX_OPTIONS_SETTING.get(settings);
11021125
if (recoverySourceSyntheticEnabled) {
11031126
if (DiscoveryNode.isStateless(settings)) {
11041127
throw new IllegalArgumentException("synthetic recovery source is only allowed in stateful");
@@ -1837,4 +1860,8 @@ public DenseVectorFieldMapper.FilterHeuristic getHnswFilterHeuristic() {
18371860
private void setHnswFilterHeuristic(DenseVectorFieldMapper.FilterHeuristic heuristic) {
18381861
this.hnswFilterHeuristic = heuristic;
18391862
}
1863+
1864+
public SeqNoFieldMapper.SeqNoIndexOptions seqNoIndexOptions() {
1865+
return seqNoIndexOptions;
1866+
}
18401867
}

server/src/main/java/org/elasticsearch/index/IndexVersions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ private static Version parseUnchecked(String version) {
168168
public static final IndexVersion DEFAULT_OVERSAMPLE_VALUE_FOR_BBQ = def(9_024_0_00, Version.LUCENE_10_2_1);
169169
public static final IndexVersion SEMANTIC_TEXT_DEFAULTS_TO_BBQ = def(9_025_0_00, Version.LUCENE_10_2_1);
170170
public static final IndexVersion DEFAULT_TO_ACORN_HNSW_FILTER_HEURISTIC = def(9_026_0_00, Version.LUCENE_10_2_1);
171+
public static final IndexVersion SEQ_NO_WITHOUT_POINTS = def(9_027_0_00, Version.LUCENE_10_2_1);
171172
/*
172173
* STOP! READ THIS FIRST! No, really,
173174
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _

server/src/main/java/org/elasticsearch/index/codec/PerFieldFormatSupplier.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.index.mapper.IdFieldMapper;
2828
import org.elasticsearch.index.mapper.Mapper;
2929
import org.elasticsearch.index.mapper.MapperService;
30+
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
3031
import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper;
3132

3233
/**
@@ -129,7 +130,10 @@ boolean useTSDBDocValuesFormat(final String field) {
129130
private boolean excludeFields(String fieldName) {
130131
// Avoid using tsdb codec for fields like _seq_no, _primary_term.
131132
// But _tsid and _ts_routing_hash should always use the tsdb codec.
132-
return fieldName.startsWith("_") && fieldName.equals("_tsid") == false && fieldName.equals("_ts_routing_hash") == false;
133+
return fieldName.startsWith("_")
134+
&& fieldName.equals("_tsid") == false
135+
&& fieldName.equals("_ts_routing_hash") == false
136+
&& fieldName.equals(SeqNoFieldMapper.NAME) == false;
133137
}
134138

135139
private boolean isTimeSeriesModeIndex() {

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

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package org.elasticsearch.index.engine;
1111

1212
import org.apache.logging.log4j.Logger;
13-
import org.apache.lucene.document.LongPoint;
1413
import org.apache.lucene.document.NumericDocValuesField;
1514
import org.apache.lucene.index.DirectoryReader;
1615
import org.apache.lucene.index.IndexCommit;
@@ -1811,7 +1810,10 @@ private DeletionStrategy planDeletionAsPrimary(Delete delete) throws IOException
18111810
private DeleteResult deleteInLucene(Delete delete, DeletionStrategy plan) throws IOException {
18121811
assert assertMaxSeqNoOfUpdatesIsAdvanced(delete.uid(), delete.seqNo(), false, false);
18131812
try {
1814-
final ParsedDocument tombstone = ParsedDocument.deleteTombstone(delete.id());
1813+
final ParsedDocument tombstone = ParsedDocument.deleteTombstone(
1814+
engineConfig.getIndexSettings().seqNoIndexOptions(),
1815+
delete.id()
1816+
);
18151817
assert tombstone.docs().size() == 1 : "Tombstone doc should have single doc [" + tombstone + "]";
18161818
tombstone.updateSeqID(delete.seqNo(), delete.primaryTerm());
18171819
tombstone.version().setLongValue(plan.versionOfDeletion);
@@ -1970,7 +1972,10 @@ private NoOpResult innerNoOp(final NoOp noOp) throws IOException {
19701972
markSeqNoAsSeen(noOp.seqNo());
19711973
if (hasBeenProcessedBefore(noOp) == false) {
19721974
try {
1973-
final ParsedDocument tombstone = ParsedDocument.noopTombstone(noOp.reason());
1975+
final ParsedDocument tombstone = ParsedDocument.noopTombstone(
1976+
engineConfig.getIndexSettings().seqNoIndexOptions(),
1977+
noOp.reason()
1978+
);
19741979
tombstone.updateSeqID(noOp.seqNo(), noOp.primaryTerm());
19751980
// A noop tombstone does not require a _version but it's added to have a fully dense docvalues for the version
19761981
// field. 1L is selected to optimize the compression because it might probably be the most common value in
@@ -2753,10 +2758,10 @@ private IndexWriterConfig getIndexWriterConfig() {
27532758
? SourceFieldMapper.RECOVERY_SOURCE_SIZE_NAME
27542759
: SourceFieldMapper.RECOVERY_SOURCE_NAME,
27552760
engineConfig.getIndexSettings().getMode() == IndexMode.TIME_SERIES,
2756-
softDeletesPolicy::getRetentionQuery,
2761+
() -> softDeletesPolicy.getRetentionQuery(engineConfig.getIndexSettings().seqNoIndexOptions()),
27572762
new SoftDeletesRetentionMergePolicy(
27582763
Lucene.SOFT_DELETES_FIELD,
2759-
softDeletesPolicy::getRetentionQuery,
2764+
() -> softDeletesPolicy.getRetentionQuery(engineConfig.getIndexSettings().seqNoIndexOptions()),
27602765
new PrunePostingsMergePolicy(mergePolicy, IdFieldMapper.NAME)
27612766
)
27622767
);
@@ -3215,12 +3220,7 @@ public int countChanges(String source, long fromSeqNo, long toSeqNo) throws IOEx
32153220
ensureOpen();
32163221
refreshIfNeeded(source, toSeqNo);
32173222
try (Searcher searcher = acquireSearcher(source, SearcherScope.INTERNAL)) {
3218-
return LuceneChangesSnapshot.countOperations(
3219-
searcher,
3220-
fromSeqNo,
3221-
toSeqNo,
3222-
config().getIndexSettings().getIndexVersionCreated()
3223-
);
3223+
return LuceneChangesSnapshot.countOperations(searcher, engineConfig.getIndexSettings(), fromSeqNo, toSeqNo);
32243224
} catch (Exception e) {
32253225
try {
32263226
maybeFailEngine("count changes", e);
@@ -3448,7 +3448,11 @@ private void restoreVersionMapAndCheckpointTracker(DirectoryReader directoryRead
34483448
final IndexSearcher searcher = new IndexSearcher(directoryReader);
34493449
searcher.setQueryCache(null);
34503450
final Query query = new BooleanQuery.Builder().add(
3451-
LongPoint.newRangeQuery(SeqNoFieldMapper.NAME, getPersistedLocalCheckpoint() + 1, Long.MAX_VALUE),
3451+
SeqNoFieldMapper.rangeQueryForSeqNo(
3452+
engineConfig.getIndexSettings().seqNoIndexOptions(),
3453+
getPersistedLocalCheckpoint() + 1,
3454+
Long.MAX_VALUE
3455+
),
34523456
BooleanClause.Occur.MUST
34533457
)
34543458
.add(Queries.newNonNestedFilter(indexVersionCreated), BooleanClause.Occur.MUST) // exclude non-root nested documents

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.elasticsearch.common.bytes.BytesReference;
1818
import org.elasticsearch.common.lucene.index.SequentialStoredFieldsLeafReader;
1919
import org.elasticsearch.core.Assertions;
20+
import org.elasticsearch.index.IndexSettings;
2021
import org.elasticsearch.index.IndexVersion;
2122
import org.elasticsearch.index.fieldvisitor.FieldsVisitor;
2223
import org.elasticsearch.index.mapper.MapperService;
@@ -187,12 +188,12 @@ private static boolean hasSequentialAccess(ScoreDoc[] scoreDocs) {
187188
return true;
188189
}
189190

190-
static int countOperations(Engine.Searcher engineSearcher, long fromSeqNo, long toSeqNo, IndexVersion indexVersionCreated)
191+
static int countOperations(Engine.Searcher engineSearcher, IndexSettings indexSettings, long fromSeqNo, long toSeqNo)
191192
throws IOException {
192193
if (fromSeqNo < 0 || toSeqNo < 0 || fromSeqNo > toSeqNo) {
193194
throw new IllegalArgumentException("Invalid range; from_seqno [" + fromSeqNo + "], to_seqno [" + toSeqNo + "]");
194195
}
195-
return newIndexSearcher(engineSearcher).count(rangeQuery(fromSeqNo, toSeqNo, indexVersionCreated));
196+
return newIndexSearcher(engineSearcher).count(rangeQuery(indexSettings, fromSeqNo, toSeqNo));
196197
}
197198

198199
private Translog.Operation readDocAsOp(int docIndex) throws IOException {

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
package org.elasticsearch.index.engine;
1111

12-
import org.apache.lucene.document.LongPoint;
1312
import org.apache.lucene.index.LeafReader;
1413
import org.apache.lucene.index.LeafReaderContext;
1514
import org.apache.lucene.index.NumericDocValues;
@@ -26,6 +25,7 @@
2625
import org.elasticsearch.common.lucene.Lucene;
2726
import org.elasticsearch.common.lucene.search.Queries;
2827
import org.elasticsearch.core.IOUtils;
28+
import org.elasticsearch.index.IndexSettings;
2929
import org.elasticsearch.index.IndexVersion;
3030
import org.elasticsearch.index.mapper.InferenceMetadataFieldsMapper;
3131
import org.elasticsearch.index.mapper.MapperService;
@@ -47,7 +47,7 @@
4747
public abstract class SearchBasedChangesSnapshot implements Translog.Snapshot, Closeable {
4848
public static final int DEFAULT_BATCH_SIZE = 1024;
4949

50-
private final IndexVersion indexVersionCreated;
50+
private final IndexSettings indexSettings;
5151
private final IndexSearcher indexSearcher;
5252
private final ValueFetcher sourceMetadataFetcher;
5353
private final Closeable onClose;
@@ -97,7 +97,7 @@ protected SearchBasedChangesSnapshot(
9797
}
9898
};
9999

100-
this.indexVersionCreated = indexVersionCreated;
100+
this.indexSettings = mapperService.getIndexSettings();
101101
this.fromSeqNo = fromSeqNo;
102102
this.toSeqNo = toSeqNo;
103103
this.lastSeenSeqNo = fromSeqNo - 1;
@@ -109,7 +109,7 @@ protected SearchBasedChangesSnapshot(
109109
this.searchBatchSize = (int) Math.min(requestingSize, searchBatchSize);
110110

111111
this.accessStats = accessStats;
112-
this.totalHits = accessStats ? indexSearcher.count(rangeQuery(fromSeqNo, toSeqNo, indexVersionCreated)) : -1;
112+
this.totalHits = accessStats ? indexSearcher.count(rangeQuery(indexSettings, fromSeqNo, toSeqNo)) : -1;
113113
this.sourceMetadataFetcher = createSourceMetadataValueFetcher(mapperService, indexSearcher);
114114
}
115115

@@ -183,7 +183,7 @@ public void close() throws IOException {
183183
* @return TopDocs instance containing the documents in the current batch.
184184
*/
185185
protected TopDocs nextTopDocs() throws IOException {
186-
Query rangeQuery = rangeQuery(Math.max(fromSeqNo, lastSeenSeqNo), toSeqNo, indexVersionCreated);
186+
Query rangeQuery = rangeQuery(indexSettings, Math.max(fromSeqNo, lastSeenSeqNo), toSeqNo);
187187
SortField sortBySeqNo = new SortField(SeqNoFieldMapper.NAME, SortField.Type.LONG);
188188

189189
TopFieldCollectorManager collectorManager = new TopFieldCollectorManager(new Sort(sortBySeqNo), searchBatchSize, afterDoc, 0);
@@ -241,9 +241,10 @@ static IndexSearcher newIndexSearcher(Engine.Searcher engineSearcher) throws IOE
241241
return new IndexSearcher(Lucene.wrapAllDocsLive(engineSearcher.getDirectoryReader()));
242242
}
243243

244-
static Query rangeQuery(long fromSeqNo, long toSeqNo, IndexVersion indexVersionCreated) {
245-
return new BooleanQuery.Builder().add(LongPoint.newRangeQuery(SeqNoFieldMapper.NAME, fromSeqNo, toSeqNo), BooleanClause.Occur.MUST)
246-
.add(Queries.newNonNestedFilter(indexVersionCreated), BooleanClause.Occur.MUST)
244+
static Query rangeQuery(IndexSettings indexSettings, long fromSeqNo, long toSeqNo) {
245+
Query seqNoQuery = SeqNoFieldMapper.rangeQueryForSeqNo(indexSettings.seqNoIndexOptions(), fromSeqNo, toSeqNo);
246+
return new BooleanQuery.Builder().add(seqNoQuery, BooleanClause.Occur.MUST)
247+
.add(Queries.newNonNestedFilter(indexSettings.getIndexVersionCreated()), BooleanClause.Occur.MUST)
247248
.build();
248249
}
249250

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
package org.elasticsearch.index.engine;
1111

12-
import org.apache.lucene.document.LongPoint;
1312
import org.apache.lucene.search.Query;
1413
import org.elasticsearch.core.Releasable;
1514
import org.elasticsearch.core.Releasables;
@@ -147,8 +146,8 @@ synchronized long getMinRetainedSeqNo() {
147146
* Returns a soft-deletes retention query that will be used in {@link org.apache.lucene.index.SoftDeletesRetentionMergePolicy}
148147
* Documents including tombstones are soft-deleted and matched this query will be retained and won't cleaned up by merges.
149148
*/
150-
Query getRetentionQuery() {
151-
return LongPoint.newRangeQuery(SeqNoFieldMapper.NAME, getMinRetainedSeqNo(), Long.MAX_VALUE);
149+
Query getRetentionQuery(SeqNoFieldMapper.SeqNoIndexOptions seqNoIndexOptions) {
150+
return SeqNoFieldMapper.rangeQueryForSeqNo(seqNoIndexOptions, getMinRetainedSeqNo(), Long.MAX_VALUE);
152151
}
153152

154153
}

server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ protected DocumentParserContext(
264264
new HashMap<>(),
265265
null,
266266
null,
267-
SeqNoFieldMapper.SequenceIDFields.emptySeqID(),
267+
SeqNoFieldMapper.SequenceIDFields.emptySeqID(mappingParserContext.getIndexSettings().seqNoIndexOptions()),
268268
RoutingFields.fromIndexSettings(mappingParserContext.getIndexSettings()),
269269
parent,
270270
dynamic,

server/src/main/java/org/elasticsearch/index/mapper/ParsedDocument.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ public class ParsedDocument {
4545
* Create a no-op tombstone document
4646
* @param reason the reason for the no-op
4747
*/
48-
public static ParsedDocument noopTombstone(String reason) {
48+
public static ParsedDocument noopTombstone(SeqNoFieldMapper.SeqNoIndexOptions seqNoIndexOptions, String reason) {
4949
LuceneDocument document = new LuceneDocument();
50-
SeqNoFieldMapper.SequenceIDFields seqIdFields = SeqNoFieldMapper.SequenceIDFields.tombstone();
50+
var seqIdFields = SeqNoFieldMapper.SequenceIDFields.tombstone(seqNoIndexOptions);
5151
seqIdFields.addFields(document);
5252
Field versionField = VersionFieldMapper.versionField();
5353
document.add(versionField);
@@ -72,9 +72,9 @@ public static ParsedDocument noopTombstone(String reason) {
7272
* The returned document consists only _uid, _seqno, _term and _version fields; other metadata fields are excluded.
7373
* @param id the id of the deleted document
7474
*/
75-
public static ParsedDocument deleteTombstone(String id) {
75+
public static ParsedDocument deleteTombstone(SeqNoFieldMapper.SeqNoIndexOptions seqNoIndexOptions, String id) {
7676
LuceneDocument document = new LuceneDocument();
77-
SeqNoFieldMapper.SequenceIDFields seqIdFields = SeqNoFieldMapper.SequenceIDFields.tombstone();
77+
SeqNoFieldMapper.SequenceIDFields seqIdFields = SeqNoFieldMapper.SequenceIDFields.tombstone(seqNoIndexOptions);
7878
seqIdFields.addFields(document);
7979
Field versionField = VersionFieldMapper.versionField();
8080
document.add(versionField);

0 commit comments

Comments
 (0)