-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mark shard failures caused by unsupported aggregations or queries against rolled up data so Kibana can identify them #89252
Changes from 43 commits
763a9ac
e3e93ae
c11e303
37c0e98
00e08a0
bbf1e08
9e8dc17
b0e751a
dfe0bda
5ed41b2
47f9780
d31904d
967aee8
9e3e6c5
9263914
2457bf9
9550d46
b140c43
619aa14
21f0c07
b2d5bb9
d08de71
b8f4a5f
1434aec
0993e09
d96fbd0
fe79b0c
2936b6d
a9c484b
1dfba79
742c628
9e9987e
3de5555
77ab1b0
39cbfa7
37a1eb1
3297479
c0e54ef
c5f2878
076d589
cdc54c9
f381b75
1715522
bd7db95
0f2600b
3f16441
22d2347
1d31f70
9226e84
f7d737a
ada8087
1e38114
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -11,6 +11,7 @@ | |||||||||||||||||||||||||||||
import org.elasticsearch.cluster.metadata.IndexMetadata; | ||||||||||||||||||||||||||||||
import org.elasticsearch.cluster.metadata.MetadataCreateDataStreamService; | ||||||||||||||||||||||||||||||
import org.elasticsearch.cluster.routing.IndexRouting; | ||||||||||||||||||||||||||||||
import org.elasticsearch.common.Strings; | ||||||||||||||||||||||||||||||
import org.elasticsearch.common.compress.CompressedXContent; | ||||||||||||||||||||||||||||||
import org.elasticsearch.common.settings.Setting; | ||||||||||||||||||||||||||||||
import org.elasticsearch.common.settings.Settings; | ||||||||||||||||||||||||||||||
|
@@ -28,10 +29,13 @@ | |||||||||||||||||||||||||||||
import org.elasticsearch.index.mapper.RoutingFieldMapper; | ||||||||||||||||||||||||||||||
import org.elasticsearch.index.mapper.TimeSeriesIdFieldMapper; | ||||||||||||||||||||||||||||||
import org.elasticsearch.index.mapper.TsidExtractingIdFieldMapper; | ||||||||||||||||||||||||||||||
import org.elasticsearch.search.aggregations.bucket.histogram.DateIntervalWrapper; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
import java.io.IOException; | ||||||||||||||||||||||||||||||
import java.time.ZoneId; | ||||||||||||||||||||||||||||||
import java.util.Arrays; | ||||||||||||||||||||||||||||||
import java.util.List; | ||||||||||||||||||||||||||||||
import java.util.Locale; | ||||||||||||||||||||||||||||||
import java.util.Map; | ||||||||||||||||||||||||||||||
import java.util.Objects; | ||||||||||||||||||||||||||||||
import java.util.function.BooleanSupplier; | ||||||||||||||||||||||||||||||
|
@@ -110,6 +114,22 @@ public DocumentDimensions buildDocumentDimensions(IndexSettings settings) { | |||||||||||||||||||||||||||||
public boolean shouldValidateTimestamp() { | ||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||
public void validateCalendarIntervalType( | ||||||||||||||||||||||||||||||
IndexSettings indexSettings, | ||||||||||||||||||||||||||||||
DateIntervalWrapper.IntervalTypeEnum intervalType, | ||||||||||||||||||||||||||||||
String valuesSourceDescription, | ||||||||||||||||||||||||||||||
String aggregationName | ||||||||||||||||||||||||||||||
) {} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||
public void validateCalendarTimeZone( | ||||||||||||||||||||||||||||||
IndexSettings indexSettings, | ||||||||||||||||||||||||||||||
ZoneId tz, | ||||||||||||||||||||||||||||||
String valuesSourceDescription, | ||||||||||||||||||||||||||||||
String aggregationName | ||||||||||||||||||||||||||||||
) {} | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
TIME_SERIES("time_series") { | ||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||
|
@@ -196,8 +216,55 @@ public DocumentDimensions buildDocumentDimensions(IndexSettings settings) { | |||||||||||||||||||||||||||||
public boolean shouldValidateTimestamp() { | ||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* For a time series index we just support 'fixed_interval' aggregations. | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I might have missed something. I thought we only wanted to limit to fixed interval for the rolled up indices. Time series indices are supposed to support all the things. I think. I certainly could be forgetting things, but that was my memory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch, this was also my understanding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't get what is wrong here...do you mean this should fail only if the date histogram aggregation runs on a rolled-up index? And not on every time series index? If that is what I missed then I have no idea how do we know if an index is a result of a rollup operation or not. Maybe we have some meta-data? I will check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the UTC/non-UTC check? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for UTC/non-UTC by my understanding. Not sure whether it's right or not, but in Kibana we currently check this via the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It should fail only if the Lines 440 to 453 in 03f3c81
|
||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||
* @param intervalType the type of interval used by the date histogram | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||
public void validateCalendarIntervalType( | ||||||||||||||||||||||||||||||
IndexSettings indexSettings, | ||||||||||||||||||||||||||||||
DateIntervalWrapper.IntervalTypeEnum intervalType, | ||||||||||||||||||||||||||||||
String valuesSourceDescription, | ||||||||||||||||||||||||||||||
String aggregationName | ||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||
if (indexSettings.getIndexMetadata().isRollupIndex() && DateIntervalWrapper.IntervalTypeEnum.CALENDAR.equals(intervalType)) { | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we want this test for all time rolled up indices. Not that there are any non-time series ones, but I think the addition of |
||||||||||||||||||||||||||||||
throw new IllegalArgumentException( | ||||||||||||||||||||||||||||||
valuesSourceDescription | ||||||||||||||||||||||||||||||
+ " is not supported for aggregation [" | ||||||||||||||||||||||||||||||
+ aggregationName | ||||||||||||||||||||||||||||||
+ "] with interval type [" | ||||||||||||||||||||||||||||||
+ intervalType.getPreferredName() | ||||||||||||||||||||||||||||||
+ "]" | ||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||
public void validateCalendarTimeZone( | ||||||||||||||||||||||||||||||
IndexSettings indexSettings, | ||||||||||||||||||||||||||||||
ZoneId tz, | ||||||||||||||||||||||||||||||
String valuesSourceDescription, | ||||||||||||||||||||||||||||||
String aggregationName | ||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||
if (indexSettings.getIndexMetadata().isRollupIndex() && tz != null && ZoneId.of("UTC").equals(tz) == false) { | ||||||||||||||||||||||||||||||
throw new IllegalArgumentException( | ||||||||||||||||||||||||||||||
valuesSourceDescription + " is not supported for aggregation [" + aggregationName + "] with timezone [" + tz + "]" | ||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
private static boolean isIndexRollup(final IndexSettings indexSettings) { | ||||||||||||||||||||||||||||||
final String sourceIndex = indexSettings.getIndexMetadata().getSettings().get(IndexMetadata.INDEX_ROLLUP_SOURCE_NAME_KEY); | ||||||||||||||||||||||||||||||
final String indexRollupStatus = indexSettings.getIndexMetadata().getSettings().get(IndexMetadata.INDEX_ROLLUP_STATUS_KEY); | ||||||||||||||||||||||||||||||
final boolean rollupSuccess = IndexMetadata.RollupTaskStatus.SUCCESS.name() | ||||||||||||||||||||||||||||||
.toLowerCase(Locale.ROOT) | ||||||||||||||||||||||||||||||
.equals(indexRollupStatus != null ? indexRollupStatus.toLowerCase(Locale.ROOT) : IndexMetadata.RollupTaskStatus.UNKNOWN); | ||||||||||||||||||||||||||||||
return Strings.isNullOrEmpty(sourceIndex) == false && rollupSuccess; | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is a duplicate. |
||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
protected static String tsdbMode() { | ||||||||||||||||||||||||||||||
return "[" + IndexSettings.MODE.getKey() + "=time_series]"; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
@@ -331,4 +398,18 @@ public static IndexMode fromString(String value) { | |||||||||||||||||||||||||||||
public String toString() { | ||||||||||||||||||||||||||||||
return getName(); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
public abstract void validateCalendarIntervalType( | ||||||||||||||||||||||||||||||
IndexSettings indexSettings, | ||||||||||||||||||||||||||||||
DateIntervalWrapper.IntervalTypeEnum intervalType, | ||||||||||||||||||||||||||||||
String valuesSourceDescription, | ||||||||||||||||||||||||||||||
String aggregationName | ||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
public abstract void validateCalendarTimeZone( | ||||||||||||||||||||||||||||||
IndexSettings indexSettings, | ||||||||||||||||||||||||||||||
ZoneId tz, | ||||||||||||||||||||||||||||||
String valueSourceDescription, | ||||||||||||||||||||||||||||||
String aggregationName | ||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.search.aggregations; | ||
|
||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.rest.RestStatus; | ||
|
||
import java.io.IOException; | ||
|
||
/** | ||
* Thrown when executing an aggregation on a time series index field whose type is not supported. | ||
* Downsampling uses specific types while aggregating some fields (like 'aggregate_metric_double'). | ||
* Such field types do not support some aggregations. | ||
*/ | ||
public class UnsupportedAggregationOnDownsampledField extends AggregationExecutionException { | ||
salvatore-campagna marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably worth leaving a note that the name of this class is part of a contract with Kibana so we shouldn't change it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we name the action "rollup" everywhere in the code, what about naming this exception Also, since this is more generic than a rollup field we can name it |
||
|
||
public UnsupportedAggregationOnDownsampledField(final String msg) { | ||
super(msg); | ||
} | ||
|
||
public UnsupportedAggregationOnDownsampledField(final StreamInput in) throws IOException { | ||
super(in); | ||
} | ||
|
||
@Override | ||
public RestStatus status() { | ||
return RestStatus.BAD_REQUEST; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the feeling this is not the best I can do here. I am working on a better way to do this at the moment but I wanted to push this change because it might be good enough. If that feeling is shared but this is considered "good enough" we could proceed merging this to unblock Kibana folks experimenting with catching exceptions. Then I can create another issue to refactor this. N.B. I am on vacation next week and Christos is on vacation too and I would like to avoid Kibana folks being stuck waiting for this.
As a result, if required, I can work on this on another PR whose purpose would be to refactor this "isRollupIndex" logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's cool as a temporary thing. Maybe a
TODO
in the code so we know we thought it was temporary when we added it.