Skip to content

Commit caf0160

Browse files
committed
Avoid double decrement on current query counter
This commit fixes a double decrement bug on the current query counter. The double decrement arises in a situation when the fetch phase is inlined for a query that is only touching one shard. After the query phase succeeds we decrement the current query counter. If the fetch phase ultimately fails, an exception is thrown and we decrement the current query counter again in the catch block. We also add assertions that all current stats counters remain non-negative at all times. Relates #24922
1 parent 32232ff commit caf0160

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

core/src/main/java/org/elasticsearch/index/search/stats/ShardSearchStats.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ public void onFailedQueryPhase(SearchContext searchContext) {
8282
computeStats(searchContext, statsHolder -> {
8383
if (searchContext.hasOnlySuggest()) {
8484
statsHolder.suggestCurrent.dec();
85+
assert statsHolder.suggestCurrent.count() >= 0;
8586
} else {
8687
statsHolder.queryCurrent.dec();
88+
assert statsHolder.queryCurrent.count() >= 0;
8789
}
8890
});
8991
}
@@ -94,9 +96,11 @@ public void onQueryPhase(SearchContext searchContext, long tookInNanos) {
9496
if (searchContext.hasOnlySuggest()) {
9597
statsHolder.suggestMetric.inc(tookInNanos);
9698
statsHolder.suggestCurrent.dec();
99+
assert statsHolder.suggestCurrent.count() >= 0;
97100
} else {
98101
statsHolder.queryMetric.inc(tookInNanos);
99102
statsHolder.queryCurrent.dec();
103+
assert statsHolder.queryCurrent.count() >= 0;
100104
}
101105
});
102106
}
@@ -116,6 +120,7 @@ public void onFetchPhase(SearchContext searchContext, long tookInNanos) {
116120
computeStats(searchContext, statsHolder -> {
117121
statsHolder.fetchMetric.inc(tookInNanos);
118122
statsHolder.fetchCurrent.dec();
123+
assert statsHolder.fetchCurrent.count() >= 0;
119124
});
120125
}
121126

@@ -176,6 +181,7 @@ public void onNewScrollContext(SearchContext context) {
176181
@Override
177182
public void onFreeScrollContext(SearchContext context) {
178183
totalStats.scrollCurrent.dec();
184+
assert totalStats.scrollCurrent.count() >= 0;
179185
totalStats.scrollMetric.inc(System.nanoTime() - context.getOriginNanoTime());
180186
}
181187

core/src/main/java/org/elasticsearch/search/SearchService.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ public SearchPhaseResult executeQueryPhase(ShardSearchRequest request, SearchTas
252252
final SearchContext context = createAndPutContext(request);
253253
final SearchOperationListener operationListener = context.indexShard().getSearchOperationListener();
254254
context.incRef();
255+
boolean queryPhaseSuccess = false;
255256
try {
256257
context.setTask(task);
257258
operationListener.onPreQueryPhase(context);
@@ -266,6 +267,7 @@ public SearchPhaseResult executeQueryPhase(ShardSearchRequest request, SearchTas
266267
contextProcessedSuccessfully(context);
267268
}
268269
final long afterQueryTime = System.nanoTime();
270+
queryPhaseSuccess = true;
269271
operationListener.onQueryPhase(context, afterQueryTime - time);
270272
if (request.numberOfShards() == 1) {
271273
return executeFetchPhase(context, operationListener, afterQueryTime);
@@ -277,7 +279,9 @@ public SearchPhaseResult executeQueryPhase(ShardSearchRequest request, SearchTas
277279
e = (e.getCause() == null || e.getCause() instanceof Exception) ?
278280
(Exception) e.getCause() : new ElasticsearchException(e.getCause());
279281
}
280-
operationListener.onFailedQueryPhase(context);
282+
if (!queryPhaseSuccess) {
283+
operationListener.onFailedQueryPhase(context);
284+
}
281285
logger.trace("Query phase failed", e);
282286
processFailure(context, e);
283287
throw ExceptionsHelper.convertToRuntime(e);

0 commit comments

Comments
 (0)