Skip to content

Commit 87d19b2

Browse files
authored
type and id are lost upon serialization of Translog.Delete. (#24586)
This was introduced in #24460: the constructor of `Translog.Delete` that takes a `StreamInput` does not set the type and id. To make it a bit more robust, I made fields final so that forgetting to set them would make the compiler complain.
1 parent 5e8b569 commit 87d19b2

File tree

4 files changed

+58
-21
lines changed

4 files changed

+58
-21
lines changed

core/src/main/java/org/elasticsearch/index/engine/Engine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,8 +1102,8 @@ public static class Delete extends Operation {
11021102
public Delete(String type, String id, Term uid, long seqNo, long primaryTerm, long version, VersionType versionType,
11031103
Origin origin, long startTime) {
11041104
super(uid, seqNo, primaryTerm, version, versionType, origin, startTime);
1105-
this.type = type;
1106-
this.id = id;
1105+
this.type = Objects.requireNonNull(type);
1106+
this.id = Objects.requireNonNull(id);
11071107
}
11081108

11091109
public Delete(String type, String id, Term uid) {

core/src/main/java/org/elasticsearch/index/translog/Translog.java

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.elasticsearch.index.IndexSettings;
4343
import org.elasticsearch.index.VersionType;
4444
import org.elasticsearch.index.engine.Engine;
45+
import org.elasticsearch.index.mapper.Uid;
4546
import org.elasticsearch.index.seqno.SequenceNumbersService;
4647
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
4748
import org.elasticsearch.index.shard.IndexShardComponent;
@@ -58,6 +59,7 @@
5859
import java.util.Collections;
5960
import java.util.Iterator;
6061
import java.util.List;
62+
import java.util.Objects;
6163
import java.util.Optional;
6264
import java.util.concurrent.atomic.AtomicBoolean;
6365
import java.util.concurrent.locks.ReadWriteLock;
@@ -919,8 +921,8 @@ public static class Index implements Operation {
919921
private final String id;
920922
private final long autoGeneratedIdTimestamp;
921923
private final String type;
922-
private long seqNo = SequenceNumbersService.UNASSIGNED_SEQ_NO;
923-
private long primaryTerm = 0;
924+
private final long seqNo;
925+
private final long primaryTerm;
924926
private final long version;
925927
private final VersionType versionType;
926928
private final BytesReference source;
@@ -950,6 +952,9 @@ public Index(StreamInput in) throws IOException {
950952
if (format >= FORMAT_SEQ_NO) {
951953
seqNo = in.readLong();
952954
primaryTerm = in.readLong();
955+
} else {
956+
seqNo = SequenceNumbersService.UNASSIGNED_SEQ_NO;
957+
primaryTerm = 0;
953958
}
954959
}
955960

@@ -976,6 +981,7 @@ public Index(String type, String id, long seqNo, long version, VersionType versi
976981
this.id = id;
977982
this.source = new BytesArray(source);
978983
this.seqNo = seqNo;
984+
this.primaryTerm = 0;
979985
this.version = version;
980986
this.versionType = versionType;
981987
this.routing = routing;
@@ -1113,27 +1119,42 @@ public long getAutoGeneratedIdTimestamp() {
11131119

11141120
public static class Delete implements Operation {
11151121

1116-
private static final int FORMAT_5_X = 2;
1117-
private static final int FORMAT_SEQ_NO = FORMAT_5_X + 1;
1122+
public static final int FORMAT_5_0 = 2; // 5.0 - 5.5
1123+
private static final int FORMAT_SINGLE_TYPE = FORMAT_5_0 + 1; // 5.5 - 6.0
1124+
private static final int FORMAT_SEQ_NO = FORMAT_SINGLE_TYPE + 1; // 6.0 - *
11181125
public static final int SERIALIZATION_FORMAT = FORMAT_SEQ_NO;
11191126

1120-
private String type, id;
1121-
private Term uid;
1122-
private long seqNo = SequenceNumbersService.UNASSIGNED_SEQ_NO;
1123-
private long primaryTerm = 0;
1124-
private long version = Versions.MATCH_ANY;
1125-
private VersionType versionType = VersionType.INTERNAL;
1127+
private final String type, id;
1128+
private final Term uid;
1129+
private final long seqNo;
1130+
private final long primaryTerm;
1131+
private final long version;
1132+
private final VersionType versionType;
11261133

11271134
public Delete(StreamInput in) throws IOException {
11281135
final int format = in.readVInt();// SERIALIZATION_FORMAT
1129-
assert format >= FORMAT_5_X : "format was: " + format;
1130-
uid = new Term(in.readString(), in.readString());
1136+
assert format >= FORMAT_5_0 : "format was: " + format;
1137+
if (format >= FORMAT_SINGLE_TYPE) {
1138+
type = in.readString();
1139+
id = in.readString();
1140+
uid = new Term(in.readString(), in.readString());
1141+
} else {
1142+
uid = new Term(in.readString(), in.readString());
1143+
// the uid was constructed from the type and id so we can
1144+
// extract them back
1145+
Uid uidObject = Uid.createUid(uid.text());
1146+
type = uidObject.type();
1147+
id = uidObject.id();
1148+
}
11311149
this.version = in.readLong();
11321150
this.versionType = VersionType.fromValue(in.readByte());
11331151
assert versionType.validateVersionForWrites(this.version);
11341152
if (format >= FORMAT_SEQ_NO) {
11351153
seqNo = in.readLong();
11361154
primaryTerm = in.readLong();
1155+
} else {
1156+
seqNo = SequenceNumbersService.UNASSIGNED_SEQ_NO;
1157+
primaryTerm = 0;
11371158
}
11381159
}
11391160

@@ -1147,8 +1168,8 @@ public Delete(String type, String id, long seqNo, Term uid) {
11471168
}
11481169

11491170
public Delete(String type, String id, Term uid, long seqNo, long primaryTerm, long version, VersionType versionType) {
1150-
this.type = type;
1151-
this.id = id;
1171+
this.type = Objects.requireNonNull(type);
1172+
this.id = Objects.requireNonNull(id);
11521173
this.uid = uid;
11531174
this.seqNo = seqNo;
11541175
this.primaryTerm = primaryTerm;
@@ -1204,6 +1225,8 @@ public Source getSource() {
12041225
@Override
12051226
public void writeTo(StreamOutput out) throws IOException {
12061227
out.writeVInt(SERIALIZATION_FORMAT);
1228+
out.writeString(type);
1229+
out.writeString(id);
12071230
out.writeString(uid.field());
12081231
out.writeString(uid.text());
12091232
out.writeLong(version);

core/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1939,7 +1939,7 @@ public void testBasicCreatedFlag() throws IOException {
19391939
indexResult = engine.index(index);
19401940
assertFalse(indexResult.isCreated());
19411941

1942-
engine.delete(new Engine.Delete(null, "1", newUid(doc)));
1942+
engine.delete(new Engine.Delete("doc", "1", newUid(doc)));
19431943

19441944
index = indexForDoc(doc);
19451945
indexResult = engine.index(index);

core/src/test/java/org/elasticsearch/index/translog/TranslogTests.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,24 +354,24 @@ public void testStats() throws IOException {
354354
{
355355
final TranslogStats stats = stats();
356356
assertThat(stats.estimatedNumberOfOperations(), equalTo(2L));
357-
assertThat(stats.getTranslogSizeInBytes(), equalTo(139L));
357+
assertThat(stats.getTranslogSizeInBytes(), equalTo(146L));
358358
}
359359

360360
translog.add(new Translog.Delete("test", "3", 2, newUid("3")));
361361
{
362362
final TranslogStats stats = stats();
363363
assertThat(stats.estimatedNumberOfOperations(), equalTo(3L));
364-
assertThat(stats.getTranslogSizeInBytes(), equalTo(181L));
364+
assertThat(stats.getTranslogSizeInBytes(), equalTo(195L));
365365
}
366366

367367
translog.add(new Translog.NoOp(3, 1, randomAlphaOfLength(16)));
368368
{
369369
final TranslogStats stats = stats();
370370
assertThat(stats.estimatedNumberOfOperations(), equalTo(4L));
371-
assertThat(stats.getTranslogSizeInBytes(), equalTo(223L));
371+
assertThat(stats.getTranslogSizeInBytes(), equalTo(237L));
372372
}
373373

374-
final long expectedSizeInBytes = 266L;
374+
final long expectedSizeInBytes = 280L;
375375
translog.rollGeneration();
376376
{
377377
final TranslogStats stats = stats();
@@ -2263,6 +2263,20 @@ public void testTranslogOpSerialization() throws Exception {
22632263
in = out.bytes().streamInput();
22642264
Translog.Delete serializedDelete = new Translog.Delete(in);
22652265
assertEquals(delete, serializedDelete);
2266+
2267+
// simulate legacy delete serialization
2268+
out = new BytesStreamOutput();
2269+
out.writeVInt(Translog.Delete.FORMAT_5_0);
2270+
out.writeString(UidFieldMapper.NAME);
2271+
out.writeString("my_type#my_id");
2272+
out.writeLong(3); // version
2273+
out.writeByte(VersionType.INTERNAL.getValue());
2274+
out.writeLong(2); // seq no
2275+
out.writeLong(0); // primary term
2276+
in = out.bytes().streamInput();
2277+
serializedDelete = new Translog.Delete(in);
2278+
assertEquals("my_type", serializedDelete.type());
2279+
assertEquals("my_id", serializedDelete.id());
22662280
}
22672281

22682282
public void testRollGeneration() throws IOException {

0 commit comments

Comments
 (0)