Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix NPE when indexing a document that just has been deleted in a tsdb index #96461

Merged
merged 6 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/96461.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 96461
summary: Fix NPE when indexing a document that just has been deleted in a tsdb index
area: TSDB
type: bug
issues: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
"basic tsdb delete":
- skip:
version: " - 8.8.99"
reason: fixed in 8.9.0

- do:
indices.create:
index: weather_sensors
body:
settings:
index:
mode: time_series
routing_path: [sensor_id, location]
time_series:
start_time: 2000-01-01T00:00:00.000Z
end_time: 2099-12-31T23:59:59.999Z
number_of_replicas: 0
number_of_shards: 1
mappings:
properties:
"@timestamp":
type: date
humidity:
type: half_float
time_series_metric: gauge
location:
type: keyword
time_series_dimension: true
sensor_id:
type: keyword
time_series_dimension: true
temperature:
type: half_float
time_series_metric: gauge

- do:
index:
index: weather_sensors
body:
"@timestamp": 2023-05-31T08:41:15.000Z
sensor_id: SYKENET-000001
location: swamp
temperature: 32.4
humidity: 88.9
- match: { _id: crxuhC8WO3aVdhvtAAABiHD35_g }
- match: { result: created }
- match: { _version: 1 }

- do:
delete:
index: weather_sensors
id: crxuhC8WO3aVdhvtAAABiHD35_g
- match: { _id: crxuhC8WO3aVdhvtAAABiHD35_g }
- match: { result: deleted }
- match: { _version: 2 }

- do:
indices.flush:
index: weather_sensors

- do:
index:
index: weather_sensors
body:
"@timestamp": 2023-05-31T08:41:15.000Z
sensor_id: SYKENET-000001
location: swamp
temperature: 32.4
humidity: 88.9
- match: { _id: crxuhC8WO3aVdhvtAAABiHD35_g }
- match: { result: created }
- match: { _version: 3 }
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ final class PerThreadIDVersionAndSeqNoLookup {
this.readerKey = readerKey;

this.loadedTimestampRange = loadTimestampRange;
if (loadTimestampRange) {
// Also check for the existence of the timestamp field, because sometimes a segment can only contain tombstone documents,
// which don't have any mapped fields (also not the timestamp field) and just some meta fields like _id, _seq_no etc.
if (loadTimestampRange && reader.getFieldInfos().fieldInfo(DataStream.TimestampField.FIXED_TIMESTAMP_FIELD) != null) {
PointValues tsPointValues = reader.getPointValues(DataStream.TimestampField.FIXED_TIMESTAMP_FIELD);
assert tsPointValues != null : "no timestamp field for reader:" + reader + " and parent:" + reader.getContext().parent.reader();
minTimestamp = LongPoint.decodeDimension(tsPointValues.getMinPackedValue(), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.uid.VersionsAndSeqNoResolver.DocIdAndVersion;
import org.elasticsearch.index.mapper.IdFieldMapper;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
import org.elasticsearch.index.mapper.VersionFieldMapper;
import org.elasticsearch.test.ESTestCase;
Expand Down Expand Up @@ -152,4 +153,19 @@ public void testLoadTimestampRange() throws Exception {
writer.close();
dir.close();
}

public void testLoadTimestampRangeWithDeleteTombstone() throws Exception {
Directory dir = newDirectory();
IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Lucene.STANDARD_ANALYZER).setMergePolicy(NoMergePolicy.INSTANCE));
writer.addDocument(ParsedDocument.deleteTombstone("_id").docs().get(0));
DirectoryReader reader = DirectoryReader.open(writer);
LeafReaderContext segment = reader.leaves().get(0);
PerThreadIDVersionAndSeqNoLookup lookup = new PerThreadIDVersionAndSeqNoLookup(segment.reader(), IdFieldMapper.NAME, true);
assertTrue(lookup.loadedTimestampRange);
assertEquals(lookup.minTimestamp, 0L);
assertEquals(lookup.maxTimestamp, Long.MAX_VALUE);
reader.close();
writer.close();
dir.close();
}
}