Skip to content

Commit 573df2d

Browse files
authored
Relax TranslogWriter#assertNoSeqNumberConflict (#31569)
If the recovery and indexing are concurrently happening, it's possible for a replica to receive the same operation twice: one from the replication, and the other from the recovery. However, these operations are not identical because we don't store the versionType of operations in the Lucene index. The TranslogWriter#assertNoSeqNumberConflict assertion has been tripped several times in the CCR branch since we use Lucene in peer-recovery. This commit relaxes that assertion by excluding the versionType from the check.
1 parent 1185ddb commit 573df2d

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

server/src/main/java/org/elasticsearch/index/translog/TranslogWriter.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,20 @@ private synchronized boolean assertNoSeqNumberConflict(long seqNo, BytesReferenc
204204
Translog.Operation newOp = Translog.readOperation(new BufferedChecksumStreamInput(data.streamInput()));
205205
Translog.Operation prvOp = Translog.readOperation(new BufferedChecksumStreamInput(previous.v1().streamInput()));
206206
// TODO: We haven't had timestamp for Index operations in Lucene yet, we need to loosen this check without timestamp.
207+
// We don't store versionType in Lucene index, we need to exclude it from this check
207208
final boolean sameOp;
208209
if (newOp instanceof Translog.Index && prvOp instanceof Translog.Index) {
209210
final Translog.Index o1 = (Translog.Index) newOp;
210211
final Translog.Index o2 = (Translog.Index) prvOp;
211212
sameOp = Objects.equals(o1.id(), o2.id()) && Objects.equals(o1.type(), o2.type())
212213
&& Objects.equals(o1.source(), o2.source()) && Objects.equals(o1.routing(), o2.routing())
213214
&& o1.primaryTerm() == o2.primaryTerm() && o1.seqNo() == o2.seqNo()
214-
&& o1.version() == o2.version() && o1.versionType() == o2.versionType();
215+
&& o1.version() == o2.version();
216+
} else if (newOp instanceof Translog.Delete && prvOp instanceof Translog.Delete) {
217+
final Translog.Delete o1 = (Translog.Delete) newOp;
218+
final Translog.Delete o2 = (Translog.Delete) prvOp;
219+
sameOp = Objects.equals(o1.id(), o2.id()) && Objects.equals(o1.type(), o2.type())
220+
&& o1.primaryTerm() == o2.primaryTerm() && o1.seqNo() == o2.seqNo() && o1.version() == o2.version();
215221
} else {
216222
sameOp = false;
217223
}

server/src/test/java/org/elasticsearch/versioning/SimpleVersioningIT.java

+3
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,9 @@ public void testSpecialVersioning() {
800800
IndexResponse doc3 = client().prepareIndex("test", "type", "1").setSource("field", "value3")
801801
.setVersion(Versions.MATCH_DELETED).setVersionType(VersionType.INTERNAL).execute().actionGet();
802802
assertThat(doc3.getVersion(), equalTo(3L));
803+
IndexResponse doc4 = client().prepareIndex("test", "type", "1").setSource("field", "value4")
804+
.setVersion(4L).setVersionType(VersionType.EXTERNAL_GTE).execute().actionGet();
805+
assertThat(doc4.getVersion(), equalTo(4L));
803806
// Make sure that these versions are replicated correctly
804807
client().admin().indices().prepareUpdateSettings("test")
805808
.setSettings(Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1)).get();

0 commit comments

Comments
 (0)