Skip to content

Commit 9cb38ae

Browse files
Add ability to reindex RED shards
1 parent 9c177bd commit 9cb38ae

File tree

8 files changed

+109
-6
lines changed

8 files changed

+109
-6
lines changed

docs/reference/docs/reindex.asciidoc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,3 +1255,24 @@ POST _reindex
12551255

12561256
<1> `_reindex` defaults to sorting by `_doc` so `random_score` will not have any
12571257
effect unless you override the sort to `_score`.
1258+
1259+
[float]
1260+
==== Reindexing RED shards
1261+
1262+
`_reindex` by default fails if a shard is unavailable (red). It is possible to
1263+
reindex only the available shards using:
1264+
1265+
[source,js]
1266+
----------------------------------------------------------------
1267+
POST _reindex?allow_partial_search_results=true
1268+
{
1269+
"source": {
1270+
"index": "twitter"
1271+
},
1272+
"dest": {
1273+
"index": "red_twitter"
1274+
}
1275+
}
1276+
----------------------------------------------------------------
1277+
// CONSOLE
1278+
// TEST[setup:big_twitter]

modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ protected ReindexRequest buildRequest(RestRequest request) throws IOException {
6464
if (request.hasParam("scroll")) {
6565
internal.setScroll(parseTimeValue(request.param("scroll"), "scroll"));
6666
}
67+
68+
if (request.hasParam("allow_partial_search_results")) {
69+
internal.getSearchRequest().allowPartialSearchResults(request.paramAsBoolean("allow_partial_search_results",false));
70+
}
71+
6772
return internal;
6873
}
6974
}

modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuilders.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,13 @@ static Request initialSearch(SearchRequest searchRequest, BytesReference query,
125125
request.addParameter(storedFieldsParamName, fields.toString());
126126
}
127127

128+
// allow_partial_results introduced in 6.3, running remote reindex against earlier versions still silently discards RED shards.
128129
if (remoteVersion.onOrAfter(Version.fromId(6030099))) {
129-
// allow_partial_results introduced in 6.3, running remote reindex against earlier versions still silently discards RED shards.
130-
request.addParameter("allow_partial_search_results", "false");
130+
boolean allowPartialSearchResults = searchRequest.allowPartialSearchResults() == Boolean.TRUE;
131+
// be explicit always from 7.5 to stop relying on the default.
132+
if (allowPartialSearchResults == false || remoteVersion.onOrAfter(Version.V_7_5_0)) {
133+
request.addParameter("allow_partial_search_results", Boolean.toString(allowPartialSearchResults));
134+
}
131135
}
132136

133137
// EMPTY is safe here because we're not calling namedObject

modules/reindex/src/test/java/org/elasticsearch/index/reindex/ClientScrollableHitSourceTests.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,18 +106,26 @@ private void dotestBasicsWithRetry(int retries, int minFailures, int maxFailures
106106
TaskId parentTask = new TaskId("thenode", randomInt());
107107
AtomicInteger actualSearchRetries = new AtomicInteger();
108108
int expectedSearchRetries = 0;
109+
SearchRequest searchRequest = new SearchRequest().scroll("1m");
110+
boolean allowPartialSearchResults = randomBoolean();
111+
if (allowPartialSearchResults || randomBoolean()) {
112+
searchRequest.allowPartialSearchResults(allowPartialSearchResults);
113+
}
109114
ClientScrollableHitSource hitSource = new ClientScrollableHitSource(logger, BackoffPolicy.constantBackoff(TimeValue.ZERO, retries),
110115
threadPool, actualSearchRetries::incrementAndGet, responses::add, failureHandler,
111116
new ParentTaskAssigningClient(client, parentTask),
112-
new SearchRequest().scroll("1m"));
117+
searchRequest);
113118

114119
hitSource.start();
115120
for (int retry = 0; retry < randomIntBetween(minFailures, maxFailures); ++retry) {
116121
client.fail(SearchAction.INSTANCE, new EsRejectedExecutionException());
117122
client.awaitOperation();
118123
++expectedSearchRetries;
119124
}
120-
client.validateRequest(SearchAction.INSTANCE, (SearchRequest r) -> assertTrue(r.allowPartialSearchResults() == Boolean.FALSE));
125+
126+
// we explicitly set it on 7.5+, to not rely on the default anymore.
127+
client.validateRequest(SearchAction.INSTANCE,
128+
(SearchRequest r) -> assertTrue(r.allowPartialSearchResults() == allowPartialSearchResults));
121129
SearchResponse searchResponse = createSearchResponse();
122130
client.respond(SearchAction.INSTANCE, searchResponse);
123131

modules/reindex/src/test/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuildersTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,22 @@ public void testInitialSearchDisallowPartialResults() {
195195
assertThat(params.keySet(), not(contains(allowPartialParamName)));
196196
}
197197

198+
public void testInitialSearchExplicitlyAllowPartialResults() {
199+
final String allowPartialParamName = "allow_partial_search_results";
200+
201+
BytesReference query = new BytesArray("{}");
202+
SearchRequest searchRequest = new SearchRequest().source(new SearchSourceBuilder()).allowPartialSearchResults(true);
203+
204+
// we explicitly set it against 7.5+, to not rely on the default anymore.
205+
Version allowVersion = Version.fromId(between(Version.V_7_5_0.id, Version.CURRENT.id));
206+
Map<String, String> params = initialSearch(searchRequest, query, allowVersion).getParameters();
207+
assertEquals("true", params.get(allowPartialParamName));
208+
209+
Version notSetVersion = Version.fromId(between(0, Version.V_7_5_0.id-1));
210+
params = initialSearch(searchRequest, query, notSetVersion).getParameters();
211+
assertThat(params.keySet(), not(contains(allowPartialParamName)));
212+
}
213+
198214
private void assertScroll(Version remoteVersion, Map<String, String> params, TimeValue requested) {
199215
// V_5_0_0
200216
if (remoteVersion.before(Version.fromId(5000099))) {

modules/reindex/src/test/resources/rest-api-spec/test/reindex/35_search_failures.yml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,49 @@
11
---
2-
"Response format for search failures":
2+
"Response format for search failures with allow_partial_search_results=true":
3+
- do:
4+
indices.create:
5+
index: source
6+
body:
7+
settings:
8+
index.number_of_shards: 2
9+
10+
- do:
11+
index:
12+
index: source
13+
id: 1
14+
body: { "text": "test" }
15+
- do:
16+
indices.refresh: {}
17+
18+
- do:
19+
catch: bad_request
20+
reindex:
21+
allow_partial_search_results: true
22+
body:
23+
source:
24+
index: source
25+
query:
26+
script:
27+
script:
28+
lang: painless
29+
source: throw new IllegalArgumentException("Cats!")
30+
dest:
31+
index: dest
32+
- match: {created: 0}
33+
- match: {updated: 0}
34+
- match: {version_conflicts: 0}
35+
- match: {batches: 0}
36+
- match: {failures.0.shard: 0}
37+
- match: {failures.0.index: source}
38+
- is_true: failures.0.node
39+
- match: {failures.0.reason.type: script_exception}
40+
- match: {failures.0.reason.reason: runtime error}
41+
- match: {failures.0.reason.caused_by.type: illegal_argument_exception}
42+
- match: {failures.0.reason.caused_by.reason: Cats!}
43+
- gte: { took: 0 }
44+
45+
---
46+
"Response format for search failures normal":
347
- do:
448
indices.create:
549
index: source

rest-api-spec/src/main/resources/rest-api-spec/api/reindex.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
"max_docs":{
5353
"type":"number",
5454
"description":"Maximum number of documents to process (default: all documents)"
55+
},
56+
"allow_partial_search_results":{
57+
"type":"boolean",
58+
"default":false,
59+
"description":"Indicate if an error should be returned if there is a partial search failure or timeout"
5560
}
5661
},
5762
"body":{

server/src/main/java/org/elasticsearch/index/reindex/ClientScrollableHitSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public ClientScrollableHitSource(Logger logger, BackoffPolicy backoffPolicy, Thr
6464
super(logger, backoffPolicy, threadPool, countSearchRetry, onResponse, fail);
6565
this.client = client;
6666
this.firstSearchRequest = firstSearchRequest;
67-
firstSearchRequest.allowPartialSearchResults(false);
67+
firstSearchRequest.allowPartialSearchResults(firstSearchRequest.allowPartialSearchResults() == Boolean.TRUE);
6868
}
6969

7070
@Override

0 commit comments

Comments
 (0)