|
@@ -45,8 +45,10 @@ import org.elasticsearch.common.util.concurrent.CountDown;
|
|
|
import org.elasticsearch.core.Nullable;
|
|
|
import org.elasticsearch.core.TimeValue;
|
|
|
import org.elasticsearch.index.Index;
|
|
|
+import org.elasticsearch.index.IndexNotFoundException;
|
|
|
import org.elasticsearch.index.query.Rewriteable;
|
|
|
import org.elasticsearch.index.shard.ShardId;
|
|
|
+import org.elasticsearch.index.shard.ShardNotFoundException;
|
|
|
import org.elasticsearch.indices.ExecutorSelector;
|
|
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
|
|
import org.elasticsearch.search.SearchPhaseResult;
|
|
@@ -914,6 +916,10 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
|
|
|
) {
|
|
|
|
|
|
clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ);
|
|
|
+ if (searchRequest.allowPartialSearchResults() == null) {
|
|
|
+ // No user preference defined in search request - apply cluster service default
|
|
|
+ searchRequest.allowPartialSearchResults(searchService.defaultAllowPartialSearchResults());
|
|
|
+ }
|
|
|
|
|
|
// TODO: I think startTime() should become part of ActionRequest and that should be used both for index name
|
|
|
// date math expressions and $now in scripts. This way all apis will deal with now in the same way instead
|
|
@@ -931,7 +937,8 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
|
|
|
localIndices,
|
|
|
searchRequest.getLocalClusterAlias(),
|
|
|
searchContext,
|
|
|
- searchRequest.pointInTimeBuilder().getKeepAlive()
|
|
|
+ searchRequest.pointInTimeBuilder().getKeepAlive(),
|
|
|
+ searchRequest.allowPartialSearchResults()
|
|
|
);
|
|
|
} else {
|
|
|
final Index[] indices = resolveLocalIndices(localIndices, clusterState, timeProvider);
|
|
@@ -988,10 +995,6 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
|
|
|
// if we only have one group, then we always want Q_T_F, no need for DFS, and no need to do THEN since we hit one shard
|
|
|
searchRequest.searchType(QUERY_THEN_FETCH);
|
|
|
}
|
|
|
- if (searchRequest.allowPartialSearchResults() == null) {
|
|
|
- // No user preference defined in search request - apply cluster service default
|
|
|
- searchRequest.allowPartialSearchResults(searchService.defaultAllowPartialSearchResults());
|
|
|
- }
|
|
|
if (searchRequest.isSuggestOnly()) {
|
|
|
// disable request cache if we have only suggest
|
|
|
searchRequest.requestCache(false);
|
|
@@ -1413,22 +1416,35 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
|
|
|
OriginalIndices originalIndices,
|
|
|
String localClusterAlias,
|
|
|
SearchContextId searchContext,
|
|
|
- TimeValue keepAlive
|
|
|
+ TimeValue keepAlive,
|
|
|
+ boolean allowPartialSearchResults
|
|
|
) {
|
|
|
final List<SearchShardIterator> iterators = new ArrayList<>(searchContext.shards().size());
|
|
|
for (Map.Entry<ShardId, SearchContextIdForNode> entry : searchContext.shards().entrySet()) {
|
|
|
final SearchContextIdForNode perNode = entry.getValue();
|
|
|
if (Strings.isEmpty(perNode.getClusterAlias())) {
|
|
|
final ShardId shardId = entry.getKey();
|
|
|
- final ShardIterator shards = OperationRouting.getShards(clusterState, shardId);
|
|
|
- final List<String> targetNodes = new ArrayList<>(shards.size());
|
|
|
- targetNodes.add(perNode.getNode());
|
|
|
- if (perNode.getSearchContextId().getSearcherId() != null) {
|
|
|
- for (ShardRouting shard : shards) {
|
|
|
- if (shard.currentNodeId().equals(perNode.getNode()) == false) {
|
|
|
- targetNodes.add(shard.currentNodeId());
|
|
|
+ final List<String> targetNodes = new ArrayList<>(2);
|
|
|
+ // Prefer executing shard requests on nodes that are part of PIT first.
|
|
|
+ if (clusterState.nodes().nodeExists(perNode.getNode())) {
|
|
|
+ targetNodes.add(perNode.getNode());
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ final ShardIterator shards = OperationRouting.getShards(clusterState, shardId);
|
|
|
+ if (perNode.getSearchContextId().getSearcherId() != null) {
|
|
|
+ for (ShardRouting shard : shards) {
|
|
|
+ if (shard.currentNodeId().equals(perNode.getNode()) == false) {
|
|
|
+ targetNodes.add(shard.currentNodeId());
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ } catch (IndexNotFoundException | ShardNotFoundException e) {
|
|
|
+ // We can hit these exceptions if the index was deleted after creating PIT or the cluster state on
|
|
|
+ // this coordinating node is outdated. It's fine to ignore these extra "retry-able" target shards
|
|
|
+ // when allowPartialSearchResults is false
|
|
|
+ if (allowPartialSearchResults == false) {
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
}
|
|
|
OriginalIndices finalIndices = new OriginalIndices(
|
|
|
new String[] { shardId.getIndexName() },
|