From a58d9a1dd0f47f80bad75eee54ec13c6b32843c5 Mon Sep 17 00:00:00 2001 From: mikemccand Date: Mon, 4 Aug 2014 09:14:09 -0400 Subject: [PATCH] Core: simultaneous create/delete against same id can cause silently inconsistent replica If simultaneous create & delete operations arrive against the same id, it's possible that primary and replica see those operations in different orders, which may result in replica throwing DocumentAlreadyExistsException when the primary didn't which would lead to replica being inconsistent (missing a document that primary had indexed). This push fixes the issue, by never throwing DAEE from the replica on create. Closes #7146 #7142 --- ...nsportShardReplicationOperationAction.java | 7 +--- .../index/engine/internal/InternalEngine.java | 34 +++++++++++-------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/elasticsearch/action/support/replication/TransportShardReplicationOperationAction.java b/src/main/java/org/elasticsearch/action/support/replication/TransportShardReplicationOperationAction.java index 8f5c904b8fe..e1d2b078a0d 100644 --- a/src/main/java/org/elasticsearch/action/support/replication/TransportShardReplicationOperationAction.java +++ b/src/main/java/org/elasticsearch/action/support/replication/TransportShardReplicationOperationAction.java @@ -46,7 +46,6 @@ import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.AbstractRunnable; -import org.elasticsearch.index.engine.DocumentAlreadyExistsException; import org.elasticsearch.index.engine.VersionConflictEngineException; import org.elasticsearch.index.service.IndexService; import org.elasticsearch.index.shard.service.IndexShard; @@ -168,14 +167,10 @@ public abstract class TransportShardReplicationOperationAction 1) { - writer.addDocuments(create.docs(), create.analyzer()); + if (doUpdate) { + if (create.docs().size() > 1) { + writer.updateDocuments(create.uid(), create.docs(), create.analyzer()); + } else { + writer.updateDocument(create.uid(), create.docs().get(0), create.analyzer()); + } } else { - writer.addDocument(create.docs().get(0), create.analyzer()); + if (create.docs().size() > 1) { + writer.addDocuments(create.docs(), create.analyzer()); + } else { + writer.addDocument(create.docs().get(0), create.analyzer()); + } } Translog.Location translogLocation = translog.add(new Translog.Create(create));