Skip to content

Do not abort shard bulk on expansion rejection - #158235

Merged
fcofdez merged 5 commits into
elastic:mainfrom
fcofdez:fix-mid-bulk-indexing-pressure-rejection
Sep 1, 2026
Merged

fcofdez merged 5 commits into
elastic:mainfrom
fcofdez:fix-mid-bulk-indexing-pressure-rejection

Conversation

@fcofdez

@fcofdez fcofdez commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

An indexing pressure rejection could be thrown from the middle of
the primary bulk item loop, since setRequestToExecute tracked
expanded bytes for every item. The exception escaped
performOnPrimary and aborted the whole BulkShardRequest before
replication, so operations already applied to the primary were
never replicated, permanently stranding the replica local
checkpoint below max_seq_no and pinning the global checkpoint.

Track the expansion only for translated updates, within the item
try/catch, so a rejection fails just that update and the remaining
operations execute and replicate normally.

Closes #158212

An indexing pressure rejection could be thrown from the middle of
the primary bulk item loop, since setRequestToExecute tracked
expanded bytes for every item. The exception escaped
performOnPrimary and aborted the whole BulkShardRequest before
replication, so operations already applied to the primary were
never replicated, permanently stranding the replica local
checkpoint below max_seq_no and pinning the global checkpoint.

Track the expansion only for translated updates, within the item
try/catch, so a rejection fails just that update and the remaining
operations execute and replicate normally.

Closes elastic#158212
@fcofdez fcofdez added >bug :Distributed/CRUD A catch all label for issues around indexing, updating and getting a doc by id. Not search. Team:Distributed Meta label for distributed team. v9.6.0 v9.5.3 labels Sep 1, 2026
@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

Hi @fcofdez, I've created a changelog YAML for you.

@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

🔍 Preview links for changed docs

⏳ Building and deploying preview... View progress

This comment will be updated with preview links when the build is complete.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Important: Docs version tagging

👋 Thanks for updating the docs! Just a friendly reminder that our docs are now cumulative. This means all 9.x versions are documented on the same page and published off of the main branch, instead of creating separate pages for each minor version.

We use applies_to tags to mark version-specific features and changes.

Expand for a quick overview

When to use applies_to tags:

✅ At the page level to indicate which products/deployments the content applies to (mandatory)
✅ When features change state (e.g. preview, ga) in a specific version
✅ When availability differs across deployments and environments

What NOT to do:

❌ Don't remove or replace information that applies to an older version
❌ Don't add new information that applies to a specific version without an applies_to tag
❌ Don't forget that applies_to tags can be used at the page, section, and inline level

🤔 Need help?

@tlrx
tlrx self-requested a review September 1, 2026 10:19

@henningandersen henningandersen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

private void assertLocalCheckpointsReachMaxSeqNo() throws Exception {
assertBusy(() -> {
for (ShardStats shardStats : indicesAdmin().prepareStats(INDEX_NAME).get().getShards()) {
final SeqNoStats seqNoStats = shardStats.getSeqNoStats();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a double check, can we also verify that the max is the same across the copies?

Can be a follow-up.

@tlrx tlrx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I wonder if ShardBatchIndexer suffered from the same bug and if so, if it deserves its own test in a follow-up.

}
assertEquals(1L, primaryPressure.stats().getPrimaryRejections());

assertLocalCheckpointsReachMaxSeqNo();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible follow-up, could we also ESIntegTestCase#assertSameDocIdsOnShards?

@fcofdez

fcofdez commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

I wonder if ShardBatchIndexer suffered from the same bug and if so, if it deserves its own test in a follow-up.

AFAIK, the batch mode does not support updates and fallbacks into the sequential mode

/**
* Checks whether the batch indexing path can be used for this request.
* Returns true if batch indexing is enabled, a source batch is present, synthetic source is active,
* and all operations are index/create (no deletes, no updates).
*/
public boolean canUseBatchIndexing(BulkShardRequest request) {
if (batchIndexingEnabled.isEnabled() == false) {
return false;
}
if (request.getBulkShardBatch() == null) {
return false;
}
for (BulkItemRequest item : request.items()) {
final DocWriteRequest.OpType opType = item.request().opType();
if (opType != DocWriteRequest.OpType.INDEX && opType != DocWriteRequest.OpType.CREATE) {
return false;
}
}
return true;
}
. With the changes in the PR we should be good on that front.

@fcofdez fcofdez added the auto-backport Automatically create backport pull requests when merged label Sep 1, 2026
@fcofdez
fcofdez merged commit 3dea399 into elastic:main Sep 1, 2026
39 checks passed
@fcofdez

fcofdez commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the reviews!

@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

💔 Backport failed

Status Branch Result
❌ 9.5 Commit could not be cherrypicked due to conflicts

You can use sqren/backport to manually backport by running backport --upstream elastic/elasticsearch --pr 158235

elasticsearchmachine pushed a commit that referenced this pull request Sep 1, 2026
An indexing pressure rejection could be thrown from the middle of the
primary bulk item loop, since setRequestToExecute tracked expanded bytes
for every item. The exception escaped performOnPrimary and aborted the
whole BulkShardRequest before replication, so operations already applied
to the primary were never replicated, permanently stranding the replica
local checkpoint below max_seq_no and pinning the global checkpoint.

Track the expansion only for translated updates, within the item
try/catch, so a rejection fails just that update and the remaining
operations execute and replicate normally.

Closes #158212 Backport of #158235
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-backport Automatically create backport pull requests when merged backport pending >bug :Distributed/CRUD A catch all label for issues around indexing, updating and getting a doc by id. Not search. Team:Distributed Meta label for distributed team. v9.5.3 v9.6.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Indexing pressure handling can result in documents missing from replica shards

5 participants