Skip to content

[BUG] TransportUpdateAction trigger refresh for every failed retry attempt also during conflict #15261

@shwetathareja

Description

@shwetathareja

Describe the bug

_update API allows to update a document using document Id. But, in case there are concurrent updates and user has provided retry_on_conflict > 0 and refresh=true, OpenSearch will internally get the new document and re-attempt the update operation. But as the previous attempt failed, it shouldn't trigger any refresh rather refresh only when update has succeeded. Today, OpenSearch triggers refreshes for failed attempts as well. This can results 1000s of refreshes every minute in case of lot of conflicts which impacts indexing performance badly.

TransportUpdateAction triggers the client.bulk()

client.bulk(toSingleItemBulkRequest(indexRequest), wrapBulkResponse(ActionListener.<IndexResponse>wrap(response -> {

and bulk operation in case of exception also, it returns true for a single document

if (opType == DocWriteRequest.OpType.UPDATE) {
final UpdateRequest updateRequest = (UpdateRequest) context.getCurrent();
try {
updateResult = updateHelper.prepare(updateRequest, context.getPrimary(), nowInMillisSupplier);
} catch (Exception failure) {
// we may fail translating a update to index or delete operation
// we use index result to communicate failure while translating update request
final Engine.Result result = new Engine.IndexResult(failure, updateRequest.version());
context.setRequestToExecute(updateRequest);
context.markOperationAsExecuted(result);
context.markAsCompleted(context.getExecutionResult());
return true;
}

This results in setting operation failure as null and AsyncAfterWriteAction triggers refresh as part of runPostReplicationActions

private void finishRequest() {
ActionListener.completeWith(
listener,
() -> new WritePrimaryResult<>(
context.getBulkShardRequest(),
context.buildShardResponse(),
context.getLocationToSync(),
null,
context.getPrimary(),
logger
)
);
}
}.run();

Related component

Indexing

To Reproduce

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior

In case _update API is triggered with retry_on_conflict > 0 and refresh = true, it should refresh only when update has succeeded and not for failed attempts.

Additional Details

No response

Metadata

Metadata

Assignees

Labels

IndexingIndexing, Bulk Indexing and anything related to indexingbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions