Skip to content

Commit 3f30e38

Browse files
Fix enrich policy runner exception handling on empty segments response (#111290) (#111371)
* Fix enrich segment action listener exception logic * Update docs/changelog/111290.yaml Co-authored-by: Elastic Machine <[email protected]>
1 parent d43021e commit 3f30e38

File tree

4 files changed

+325
-37
lines changed

4 files changed

+325
-37
lines changed

docs/changelog/111290.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 111290
2+
summary: Fix enrich policy runner exception handling on empty segments response
3+
area: Ingest Node
4+
type: bug
5+
issues: []

server/src/main/java/org/elasticsearch/action/admin/indices/segments/IndicesSegmentResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class IndicesSegmentResponse extends ChunkedBroadcastResponse {
3636

3737
private volatile Map<String, IndexSegments> indicesSegments;
3838

39-
IndicesSegmentResponse(
39+
public IndicesSegmentResponse(
4040
ShardSegments[] shards,
4141
int totalShards,
4242
int successfulShards,

x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/EnrichPolicyRunner.java

Lines changed: 69 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
2626
import org.elasticsearch.action.admin.indices.segments.IndexSegments;
2727
import org.elasticsearch.action.admin.indices.segments.IndexShardSegments;
28-
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentResponse;
2928
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsRequest;
3029
import org.elasticsearch.action.admin.indices.segments.ShardSegments;
3130
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
3231
import org.elasticsearch.action.bulk.BulkItemResponse;
32+
import org.elasticsearch.action.support.DefaultShardOperationFailedException;
3333
import org.elasticsearch.client.internal.Client;
3434
import org.elasticsearch.client.internal.FilterClient;
3535
import org.elasticsearch.client.internal.OriginSettingClient;
@@ -572,48 +572,82 @@ private void refreshEnrichIndex(final String destinationIndexName, final int att
572572
protected void ensureSingleSegment(final String destinationIndexName, final int attempt) {
573573
enrichOriginClient().admin()
574574
.indices()
575-
.segments(new IndicesSegmentsRequest(destinationIndexName), new DelegatingActionListener<>(listener) {
576-
@Override
577-
public void onResponse(IndicesSegmentResponse indicesSegmentResponse) {
578-
IndexSegments indexSegments = indicesSegmentResponse.getIndices().get(destinationIndexName);
579-
if (indexSegments == null) {
575+
.segments(new IndicesSegmentsRequest(destinationIndexName), listener.delegateFailureAndWrap((l, indicesSegmentResponse) -> {
576+
int failedShards = indicesSegmentResponse.getFailedShards();
577+
if (failedShards > 0) {
578+
// Encountered a problem while querying the segments for the enrich index. Try and surface the problem in the log.
579+
logger.warn(
580+
"Policy [{}]: Encountered [{}] shard level failures while querying the segments for enrich index [{}]. "
581+
+ "Turn on DEBUG logging for details.",
582+
policyName,
583+
failedShards,
584+
enrichIndexName
585+
);
586+
if (logger.isDebugEnabled()) {
587+
DefaultShardOperationFailedException[] shardFailures = indicesSegmentResponse.getShardFailures();
588+
int failureNumber = 1;
589+
String logPrefix = "Policy [" + policyName + "]: Encountered shard failure [";
590+
String logSuffix = " of "
591+
+ shardFailures.length
592+
+ "] while querying segments for enrich index ["
593+
+ enrichIndexName
594+
+ "]. Shard [";
595+
for (DefaultShardOperationFailedException shardFailure : shardFailures) {
596+
logger.debug(
597+
logPrefix + failureNumber + logSuffix + shardFailure.index() + "][" + shardFailure.shardId() + "]",
598+
shardFailure.getCause()
599+
);
600+
failureNumber++;
601+
}
602+
}
603+
}
604+
IndexSegments indexSegments = indicesSegmentResponse.getIndices().get(destinationIndexName);
605+
if (indexSegments == null) {
606+
if (indicesSegmentResponse.getShardFailures().length == 0) {
580607
throw new ElasticsearchException(
581608
"Could not locate segment information for newly created index [{}]",
582609
destinationIndexName
583610
);
611+
} else {
612+
DefaultShardOperationFailedException shardFailure = indicesSegmentResponse.getShardFailures()[0];
613+
throw new ElasticsearchException(
614+
"Could not obtain segment information for newly created index [{}]; shard info [{}][{}]",
615+
shardFailure.getCause(),
616+
destinationIndexName,
617+
shardFailure.index(),
618+
shardFailure.shardId()
619+
);
584620
}
585-
Map<Integer, IndexShardSegments> indexShards = indexSegments.getShards();
586-
assert indexShards.size() == 1 : "Expected enrich index to contain only one shard";
587-
ShardSegments[] shardSegments = indexShards.get(0).shards();
588-
assert shardSegments.length == 1 : "Expected enrich index to contain no replicas at this point";
589-
ShardSegments primarySegments = shardSegments[0];
590-
if (primarySegments.getSegments().size() > 1) {
591-
int nextAttempt = attempt + 1;
592-
if (nextAttempt > maxForceMergeAttempts) {
593-
delegate.onFailure(
594-
new ElasticsearchException(
595-
"Force merging index [{}] attempted [{}] times but did not result in one segment.",
596-
destinationIndexName,
597-
attempt,
598-
maxForceMergeAttempts
599-
)
600-
);
601-
} else {
602-
logger.debug(
603-
"Policy [{}]: Force merge result contains more than one segment [{}], retrying (attempt {}/{})",
604-
policyName,
605-
primarySegments.getSegments().size(),
606-
nextAttempt,
607-
maxForceMergeAttempts
608-
);
609-
forceMergeEnrichIndex(destinationIndexName, nextAttempt);
610-
}
621+
}
622+
Map<Integer, IndexShardSegments> indexShards = indexSegments.getShards();
623+
assert indexShards.size() == 1 : "Expected enrich index to contain only one shard";
624+
ShardSegments[] shardSegments = indexShards.get(0).shards();
625+
assert shardSegments.length == 1 : "Expected enrich index to contain no replicas at this point";
626+
ShardSegments primarySegments = shardSegments[0];
627+
if (primarySegments.getSegments().size() > 1) {
628+
int nextAttempt = attempt + 1;
629+
if (nextAttempt > maxForceMergeAttempts) {
630+
throw new ElasticsearchException(
631+
"Force merging index [{}] attempted [{}] times but did not result in one segment.",
632+
destinationIndexName,
633+
attempt,
634+
maxForceMergeAttempts
635+
);
611636
} else {
612-
// Force merge down to one segment successful
613-
setIndexReadOnly(destinationIndexName);
637+
logger.debug(
638+
"Policy [{}]: Force merge result contains more than one segment [{}], retrying (attempt {}/{})",
639+
policyName,
640+
primarySegments.getSegments().size(),
641+
nextAttempt,
642+
maxForceMergeAttempts
643+
);
644+
forceMergeEnrichIndex(destinationIndexName, nextAttempt);
614645
}
646+
} else {
647+
// Force merge down to one segment successful
648+
setIndexReadOnly(destinationIndexName);
615649
}
616-
});
650+
}));
617651
}
618652

619653
private void setIndexReadOnly(final String destinationIndexName) {

0 commit comments

Comments
 (0)