diff --git a/docs/_docs/monitoring-metrics/new-metrics.adoc b/docs/_docs/monitoring-metrics/new-metrics.adoc index b07cb629b4c26..1fad05a13a5ba 100644 --- a/docs/_docs/monitoring-metrics/new-metrics.adoc +++ b/docs/_docs/monitoring-metrics/new-metrics.adoc @@ -522,4 +522,5 @@ Register name: `sql.queries.user` |canceled| long | The number of canceled SQL queries. |resultSetSizeHistogram| histogram | Histogram of fetched result set sizes for SQL queries. |maxResultSetSize| max value | Maximum fetched result set size for SQL queries. +|bigResultSetEventsCount| long | Number of events when a SQL query produced a big result set. |=== diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/SqlDiagnosticIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/SqlDiagnosticIntegrationTest.java index 5eb2f511ec0a8..9436dbad94aa7 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/SqlDiagnosticIntegrationTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/SqlDiagnosticIntegrationTest.java @@ -97,6 +97,7 @@ import static org.apache.ignite.internal.processors.performancestatistics.AbstractPerformanceStatisticsTest.stopCollectStatisticsAndRead; import static org.apache.ignite.internal.processors.query.QueryParserMetricsHolder.QUERY_PARSER_METRIC_GROUP_NAME; import static org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor.IGNITE_CALCITE_USE_QUERY_BLOCKING_TASK_EXECUTOR; +import static org.apache.ignite.internal.processors.query.running.HeavyQueriesTracker.BIG_RESULT_SET_EVENTS_CNT; import static org.apache.ignite.internal.processors.query.running.HeavyQueriesTracker.BIG_RESULT_SET_MSG; import static org.apache.ignite.internal.processors.query.running.HeavyQueriesTracker.LONG_QUERY_ERROR_MSG; import static org.apache.ignite.internal.processors.query.running.HeavyQueriesTracker.LONG_QUERY_EXEC_MSG; @@ -874,6 +875,20 @@ public void testBigResultSet() throws Exception { assertTrue(logLsnr2.check(1000L)); } + /** */ + @Test + public void testBigResultSetMetric() { + grid(0).context().query().runningQueryManager().heavyQueriesTracker() + .setResultSetSizeThreshold(BIG_RESULT_SET_THRESHOLD); + + sql(grid(0), "SELECT * FROM TABLE(SYSTEM_RANGE(1, ?))", BIG_RESULT_SET_THRESHOLD * 2 + 1); + + LongMetric metric = grid(0).context().metric().registry(SQL_USER_QUERIES_REG_NAME) + .findMetric(BIG_RESULT_SET_EVENTS_CNT); + + assertNotNull("Metric is not registered", metric); + assertTrue("Metric is not incremented", metric.value() > 0); + } /** */ @Test diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/running/HeavyQueriesTracker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/running/HeavyQueriesTracker.java index 72ca9731ecf5a..353da1508d1f7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/running/HeavyQueriesTracker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/running/HeavyQueriesTracker.java @@ -23,6 +23,7 @@ import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.IgniteInterruptedCheckedException; +import org.apache.ignite.internal.processors.metric.impl.AtomicLongMetric; import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; @@ -54,6 +55,12 @@ public final class HeavyQueriesTracker { /** */ public static final String BIG_RESULT_SET_MSG = "Query produced big result set."; + /** Big result set events count metric name. */ + public static final String BIG_RESULT_SET_EVENTS_CNT = "bigResultSetEventsCount"; + + /** Big result set events count metric description. */ + private static final String BIG_RESULT_SET_EVENTS_CNT_DESC = "Number of events when a SQL query produced a big result set."; + /** Queries collection. Sorted collection isn't used to reduce 'put' time. */ private final ConcurrentHashMap qrys = new ConcurrentHashMap<>(); @@ -63,6 +70,9 @@ public final class HeavyQueriesTracker { /** Logger. */ private final IgniteLogger log; + /** Big result set events count metric. */ + private final AtomicLongMetric bigResultSetEvtsCnt; + /** Long query timeout milliseconds. */ private volatile long timeout; @@ -97,6 +107,9 @@ public final class HeavyQueriesTracker { public HeavyQueriesTracker(GridKernalContext ctx) { log = ctx.log(HeavyQueriesTracker.class); + bigResultSetEvtsCnt = ctx.metric().registry(RunningQueryManager.SQL_USER_QUERIES_REG_NAME) + .longMetric(BIG_RESULT_SET_EVENTS_CNT, BIG_RESULT_SET_EVENTS_CNT_DESC); + checkWorker = new GridWorker(ctx.igniteInstanceName(), "long-qry", log) { @Override protected void body() throws InterruptedException, IgniteInterruptedCheckedException { while (true) { @@ -156,7 +169,7 @@ public void stopTracking(TrackableQuery qryInfo, @Nullable Throwable err) { * @param qryInfo Query info. */ public ResultSetChecker resultSetChecker(TrackableQuery qryInfo) { - return new ResultSetChecker(log, qryInfo, rsSizeThreshold, rsSizeThresholdMult); + return new ResultSetChecker(log, qryInfo, rsSizeThreshold, rsSizeThresholdMult, bigResultSetEvtsCnt); } /** @@ -314,12 +327,22 @@ public static class ResultSetChecker { /** Big results flag. */ private boolean bigResults; + /** Big result set events count metric. */ + private final AtomicLongMetric bigResultSetEvtsCnt; + /** Ctor. */ - private ResultSetChecker(IgniteLogger log, TrackableQuery qryInfo, long threshold, int thresholdMult) { + private ResultSetChecker( + IgniteLogger log, + TrackableQuery qryInfo, + long threshold, + int thresholdMult, + AtomicLongMetric bigResultSetEvtsCnt + ) { this.log = log; this.qryInfo = qryInfo; this.threshold = threshold; this.thresholdMult = thresholdMult; + this.bigResultSetEvtsCnt = bigResultSetEvtsCnt; } /** @@ -332,6 +355,9 @@ public void checkOnFetchNext() { if (threshold > 0 && fetchedSize >= threshold) { LT.warn(log, BIG_RESULT_SET_MSG + qryInfo.queryInfo("fetched=" + fetchedSize)); + if (bigResultSetEvtsCnt != null) + bigResultSetEvtsCnt.increment(); + if (thresholdMult > 1) threshold *= thresholdMult; else