Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/changelog/120267.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pr: 120267
summary: Set allow_partial_search_results=true by default
area: EQL
type: breaking
issues: []
breaking:
title: Set allow_partial_search_results=true by default
area: REST API
details:
Before this change, in case of shard failures, EQL queries always returned an error.
With this change, they will keep running and will return partial results.
impact:
EQL queries that would previously fail due to shard failures, will now succeed and return partial results.
The previous defaults can be restored by setting `xpack.eql.default_allow_partial_results` cluster setting to `false`
or setting with `allow_partial_search_results` to `false` in the query request.
notable: false
4 changes: 2 additions & 2 deletions docs/reference/eql/eql-search-api.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ If `false`, the request returns an error if one or more shards involved in the q
If `true`, the query is executed only on the available shards, ignoring shard request timeouts and
<<shard-failures,shard failures>>.
+
Defaults to `false`.
Defaults to `true`.
+
To override the default for this field, set the
`xpack.eql.default_allow_partial_results` cluster setting to `true`.
`xpack.eql.default_allow_partial_results` cluster setting to `false`.


[IMPORTANT]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"allow_partial_search_results": {
"type":"boolean",
"description":"Control whether the query should keep running in case of shard failures, and return partial results",
"default":false
"default":true
},
"allow_partial_sequence_results": {
"type":"boolean",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,29 +187,29 @@ protected ObjectPath runQuery(String index, String query) throws Exception {
builder.field("max_samples_per_key", maxSamplesPerKey);
}
boolean allowPartialResultsInBody = randomBoolean();
if (allowPartialSearchResults != null) {
if (allowPartialResultsInBody) {

if (allowPartialResultsInBody) {
if (allowPartialSearchResults != null) {
builder.field("allow_partial_search_results", String.valueOf(allowPartialSearchResults));
if (allowPartialSequenceResults != null) {
builder.field("allow_partial_sequence_results", String.valueOf(allowPartialSequenceResults));
}
} else {
// these will be overwritten by the path params, that have higher priority than the query (JSON body) params
if (allowPartialSearchResults != null) {
builder.field("allow_partial_search_results", randomBoolean());
}
if (allowPartialSequenceResults != null) {
builder.field("allow_partial_sequence_results", randomBoolean());
}
} else if (randomBoolean()) {
builder.field("allow_partial_search_results", true);
}
if (allowPartialSequenceResults != null) {
builder.field("allow_partial_sequence_results", String.valueOf(allowPartialSequenceResults));
} else if (randomBoolean()) {
builder.field("allow_partial_sequence_results", false);
}
} else {
// Tests that don't specify a setting for these parameters should always pass.
// These params should be irrelevant.
if (randomBoolean()) {
// these will be overwritten by the path params, that have higher priority than the query (JSON body) params
if (allowPartialSearchResults != null) {
builder.field("allow_partial_search_results", randomBoolean());
} else if (randomBoolean()) {
builder.field("allow_partial_search_results", true);
}
if (randomBoolean()) {
if (allowPartialSequenceResults != null) {
builder.field("allow_partial_sequence_results", randomBoolean());
} else if (randomBoolean()) {
builder.field("allow_partial_sequence_results", false);
}
}
builder.endObject();
Expand All @@ -219,23 +219,17 @@ protected ObjectPath runQuery(String index, String query) throws Exception {
if (ccsMinimizeRoundtrips != null) {
request.addParameter("ccs_minimize_roundtrips", ccsMinimizeRoundtrips.toString());
}
if (allowPartialSearchResults != null) {
if (allowPartialResultsInBody == false) {
if (allowPartialResultsInBody == false) {
if (allowPartialSearchResults != null) {
request.addParameter("allow_partial_search_results", String.valueOf(allowPartialSearchResults));
if (allowPartialSequenceResults != null) {
request.addParameter("allow_partial_sequence_results", String.valueOf(allowPartialSequenceResults));
}
} else if (randomBoolean()) {
request.addParameter("allow_partial_search_results", String.valueOf(true));
}
} else {
// Tests that don't specify a setting for these parameters should always pass.
// These params should be irrelevant.
if (randomBoolean()) {
request.addParameter("allow_partial_search_results", String.valueOf(randomBoolean()));
}
if (randomBoolean()) {
request.addParameter("allow_partial_sequence_results", String.valueOf(randomBoolean()));
if (allowPartialSequenceResults != null) {
request.addParameter("allow_partial_sequence_results", String.valueOf(allowPartialSequenceResults));
}
}

int timeout = Math.toIntExact(timeout().millis());
RequestConfig config = RequestConfig.copy(RequestConfig.DEFAULT)
.setConnectionRequestTimeout(timeout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ expect_shard_failures = false
[[queries]]
name = "eventQueryShardFailures"
query = 'process where serial_event_id == 1 or broken == 1'
expected_event_ids = [1]
expect_shard_failures = true


[[queries]]
name = "eventQueryShardFailuresTrue"
query = 'process where serial_event_id == 1 or broken == 1'
allow_partial_search_results = true
expected_event_ids = [1]
expect_shard_failures = true
Expand All @@ -18,15 +25,13 @@ expect_shard_failures = true
[[queries]]
name = "eventQueryShardFailuresOptionalField"
query = 'process where serial_event_id == 1 and ?optional_field_default_null == null or broken == 1'
allow_partial_search_results = true
expected_event_ids = [1]
expect_shard_failures = true


[[queries]]
name = "eventQueryShardFailuresOptionalFieldMatching"
query = 'process where serial_event_id == 2 and ?subtype == "create" or broken == 1'
allow_partial_search_results = true
expected_event_ids = [2]
expect_shard_failures = true

Expand Down Expand Up @@ -64,7 +69,6 @@ sequence
[process where serial_event_id == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
expected_event_ids = [1, 2]
expect_shard_failures = false

Expand All @@ -76,6 +80,17 @@ sequence
[process where serial_event_id == 1 or broken == 1]
[process where serial_event_id == 2]
'''
expected_event_ids = []
expect_shard_failures = true


[[queries]]
name = "sequenceQueryMissingShardsTrue"
query = '''
sequence
[process where serial_event_id == 1 or broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
expected_event_ids = []
expect_shard_failures = true
Expand All @@ -88,6 +103,18 @@ sequence
[process where serial_event_id == 1 or broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_sequence_results = true
expected_event_ids = [1, 2]
expect_shard_failures = true


[[queries]]
name = "sequenceQueryMissingShardsPartialResultsTrue"
query = '''
sequence
[process where serial_event_id == 1 or broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
allow_partial_sequence_results = true
expected_event_ids = [1, 2]
Expand All @@ -101,7 +128,6 @@ sequence
[process where ?serial_event_id == 1 or broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
allow_partial_sequence_results = true
expected_event_ids = [1, 2]
expect_shard_failures = true
Expand All @@ -114,7 +140,6 @@ sequence with maxspan=100000d
[process where serial_event_id == 1 and ?subtype == "create" or broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
allow_partial_sequence_results = true
expected_event_ids = [1, 2]
expect_shard_failures = true
Expand All @@ -128,7 +153,6 @@ sequence with maxspan=100000d
![process where broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
allow_partial_sequence_results = true
expected_event_ids = [1, -1, 2]
expect_shard_failures = true
Expand All @@ -142,7 +166,6 @@ sequence with maxspan=100000d
![process where broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
allow_partial_sequence_results = true
expected_event_ids = [1, -1, 2]
expect_shard_failures = true
Expand All @@ -155,6 +178,17 @@ sample by event_subtype_full
[process where serial_event_id == 1 or broken == 1]
[process where serial_event_id == 2]
'''
expected_event_ids = [1, 2]
expect_shard_failures = true


[[queries]]
name = "sampleQueryMissingShardsPartialResultsTrue"
query = '''
sample by event_subtype_full
[process where serial_event_id == 1 or broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
expected_event_ids = [1, 2]
expect_shard_failures = true
Expand All @@ -167,7 +201,6 @@ sample by event_subtype_full
[process where serial_event_id == 1 and ?subtype == "create" or broken == 1]
[process where serial_event_id == 2]
'''
allow_partial_search_results = true
expected_event_ids = [1, 2]
expect_shard_failures = true

Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,19 @@ public void cleanUpIndex() throws IOException {
}

public void testEventsWithRequestToOldNodes() throws Exception {
assertEventsQueryOnNodes(bwcNodes);
assertEventsQueryOnNodes(bwcNodes, true);
}

public void testEventsWithRequestToUpgradedNodes() throws Exception {
assertEventsQueryOnNodes(newNodes);
assertEventsQueryOnNodes(newNodes, false);
}

public void testSequencesWithRequestToOldNodes() throws Exception {
assertSequncesQueryOnNodes(bwcNodes);
assertSequncesQueryOnNodes(bwcNodes, true);
}

public void testSequencesWithRequestToUpgradedNodes() throws Exception {
assertSequncesQueryOnNodes(newNodes);
assertSequncesQueryOnNodes(newNodes, false);
}

/**
Expand Down Expand Up @@ -268,7 +268,7 @@ public void testMultiValueFields() throws Exception {
assertTrue(testedFunctions.containsAll(availableFunctions));
}

private void assertEventsQueryOnNodes(List<TestNode> nodesList) throws Exception {
private void assertEventsQueryOnNodes(List<TestNode> nodesList, boolean oldNodes) throws Exception {
final String event = randomEvent();
Map<String, Object> expectedResponse = prepareEventsTestData(event);
try (
Expand All @@ -278,12 +278,23 @@ private void assertEventsQueryOnNodes(List<TestNode> nodesList) throws Exception
String filterPath = "filter_path=hits.events._source.@timestamp,hits.events._source.event_type,hits.events._source.sequence";

Request request = new Request("POST", index + "/_eql/search?" + filterPath);
request.setJsonEntity("{\"query\":\"" + event + " where true\",\"size\":15}");
StringBuilder payload = new StringBuilder("{\"query\":\"" + event + " where true\",\"size\":15");
// Old versions don't support this option
if (oldNodes == false) {
if (randomBoolean()) {
payload.append(", \"allow_partial_search_results\": " + randomBoolean());
}
if (randomBoolean()) {
payload.append(", \"allow_partial_sequence_results\": " + randomBoolean());
}
}
payload.append("}");
request.setJsonEntity(payload.toString());
assertBusy(() -> { assertResponse(expectedResponse, runEql(client, request)); });
}
}

private void assertSequncesQueryOnNodes(List<TestNode> nodesList) throws Exception {
private void assertSequncesQueryOnNodes(List<TestNode> nodesList, boolean oldNodes) throws Exception {
Map<String, Object> expectedResponse = prepareSequencesTestData();
try (
RestClient client = buildClient(restClientSettings(), nodesList.stream().map(TestNode::publishAddress).toArray(HttpHost[]::new))
Expand All @@ -294,7 +305,19 @@ private void assertSequncesQueryOnNodes(List<TestNode> nodesList) throws Excepti
String filter = "{\"range\":{\"@timestamp\":{\"gte\":\"1970-05-01\"}}}";

Request request = new Request("POST", index + "/_eql/search?" + filterPath);
request.setJsonEntity("{\"query\":\"" + query + "\",\"filter\":" + filter + "}");

StringBuilder payload = new StringBuilder("{\"query\":\"" + query + "\",\"filter\":" + filter);
// Old versions don't support this option
if (oldNodes == false) {
if (randomBoolean()) {
payload.append(", \"allow_partial_search_results\": " + randomBoolean());
}
if (randomBoolean()) {
payload.append(", \"allow_partial_sequence_results\": " + randomBoolean());
}
}
payload.append("}");
request.setJsonEntity(payload.toString());
assertBusy(() -> { assertResponse(expectedResponse, runEql(client, request)); });
}
}
Expand Down Expand Up @@ -410,10 +433,10 @@ private void assertMultiValueFunctionQuery(

StringBuilder payload = new StringBuilder("{\"query\":\"" + query + "\"");
if (randomBoolean()) {
payload.append(", \"allow_partial_search_results\": true");
payload.append(", \"allow_partial_search_results\": " + randomBoolean());
}
if (randomBoolean()) {
payload.append(", \"allow_partial_sequence_results\": true");
payload.append(", \"allow_partial_sequence_results\": " + randomBoolean());
}
payload.append("}");
request.setJsonEntity(payload.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,30 @@ setup:


---

"Execute query shard failures":
- do:
eql.search:
index: eql_test*
body:
query: 'process where user == "SYSTEM" and day_of_week == "Monday"'
fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"]
allow_partial_search_results: true

- match: {timed_out: false}
- match: {hits.total.value: 1}
- match: {hits.total.relation: "eq"}
- match: {hits.events.0._source.user: "SYSTEM"}
- match: {hits.events.0._id: "1"}
- match: {hits.events.0.fields.@timestamp: ["1580733296000"]}
- match: {hits.events.0.fields.id: [123]}
- match: {hits.events.0.fields.valid: [false]}
- match: {hits.events.0.fields.day_of_week: ["Monday"]}
- match: {shard_failures.0.index: "eql_test_rebel"}


---

"Execute query shard failures and with allow_partial_search_results":
- do:
eql.search:
Expand All @@ -535,7 +559,6 @@ setup:
- do:
eql.search:
index: eql_test*
allow_partial_search_results: true
body:
query: 'process where user == "SYSTEM" and day_of_week == "Monday"'
fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"]
Expand Down Expand Up @@ -575,7 +598,6 @@ setup:
body:
query: 'sequence [process where user == "SYSTEM" and day_of_week == "Monday"] [process where user == "SYSTEM" and day_of_week == "Tuesday"]'
fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"]
allow_partial_search_results: true
allow_partial_sequence_results: true

- match: {timed_out: false}
Expand All @@ -600,7 +622,6 @@ setup:
- do:
eql.search:
index: eql_test*
allow_partial_search_results: true
allow_partial_sequence_results: true
body:
query: 'sequence [process where user == "SYSTEM" and day_of_week == "Monday"] [process where user == "SYSTEM" and day_of_week == "Tuesday"]'
Expand Down
Loading