diff --git a/grafana/dashboards/metrics/cluster/dashboard.json b/grafana/dashboards/metrics/cluster/dashboard.json
index 2fffd27b25f..fd1d0257594 100644
--- a/grafana/dashboards/metrics/cluster/dashboard.json
+++ b/grafana/dashboards/metrics/cluster/dashboard.json
@@ -9112,6 +9112,132 @@
"title": "Read Stage P99 and Avg per Instance",
"type": "timeseries"
},
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "description": "Estimated maximum concurrent files by instance and type (query or compaction). Query samples are region scan limit evaluations, including memtable sources counted by the limit, rejected scans, and scans using memory budgeting. Compaction samples count all input files when building a compaction reader. A SQL query can produce multiple region scan evaluations. P95/P99 are histogram estimates, not exact per-query maxima or live open-file counts.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green"
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "short",
+ "min": 0
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 8,
+ "x": 8,
+ "y": 154
+ },
+ "id": 565,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "hideZeros": false,
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "pluginVersion": "11.6.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.95, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket{instance=~\"$datanode\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{instance}}]-[{{pod}}]-{{type}}-p95",
+ "range": true,
+ "refId": "A"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket{instance=~\"$datanode\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{instance}}]-[{{pod}}]-{{type}}-p99",
+ "range": true,
+ "refId": "B"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_sum{instance=~\"$datanode\"}[$__rate_interval])) / sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_count{instance=~\"$datanode\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{instance}}]-[{{pod}}]-{{type}}-avg",
+ "range": true,
+ "refId": "C"
+ }
+ ],
+ "title": "Scan Max Concurrent Files per Instance",
+ "type": "timeseries"
+ },
{
"datasource": {
"type": "prometheus",
@@ -9176,7 +9302,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 8,
+ "x": 16,
"y": 154
},
"id": 490,
@@ -9292,8 +9418,8 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 16,
- "y": 154
+ "x": 0,
+ "y": 162
},
"id": 495,
"options": {
@@ -9391,7 +9517,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 0,
+ "x": 8,
"y": 162
},
"id": 501,
@@ -9505,7 +9631,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 8,
+ "x": 16,
"y": 162
},
"id": 502,
@@ -9619,8 +9745,8 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 16,
- "y": 162
+ "x": 0,
+ "y": 170
},
"id": 503,
"options": {
@@ -9736,7 +9862,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 0,
+ "x": 8,
"y": 170
},
"id": 504,
diff --git a/grafana/dashboards/metrics/cluster/dashboard.md b/grafana/dashboards/metrics/cluster/dashboard.md
index 455268cdd43..1c167af5152 100644
--- a/grafana/dashboards/metrics/cluster/dashboard.md
+++ b/grafana/dashboards/metrics/cluster/dashboard.md
@@ -104,6 +104,7 @@
| Write Rows per Instance | `sum by (instance, pod) (rate(greptime_mito_write_rows_total{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Ingestion size by row counts. | `prometheus` | `rowsps` | `[{{instance}}]-[{{pod}}]` |
| Read Stage OPS per Instance | `sum by(instance, pod) (rate(greptime_mito_read_stage_elapsed_count{instance=~"$datanode", stage="total"}[$__rate_interval]))` | `timeseries` | Read Stage OPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]` |
| Read Stage P99 and Avg per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))`
`sum by(instance, pod, stage) (rate(greptime_mito_read_stage_elapsed_sum{instance=~"$datanode"}[$__rate_interval])) / sum by(instance, pod, stage) (rate(greptime_mito_read_stage_elapsed_count{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Read Stage P99 and average per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
+| Scan Max Concurrent Files per Instance | `histogram_quantile(0.95, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket{instance=~"$datanode"}[$__rate_interval])))`
`histogram_quantile(0.99, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket{instance=~"$datanode"}[$__rate_interval])))`
`sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_sum{instance=~"$datanode"}[$__rate_interval])) / sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_count{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Estimated maximum concurrent files by instance and type (query or compaction). Query samples are region scan limit evaluations, including memtable sources counted by the limit, rejected scans, and scans using memory budgeting. Compaction samples count all input files when building a compaction reader. A SQL query can produce multiple region scan evaluations. P95/P99 are histogram estimates, not exact per-query maxima or live open-file counts. | `prometheus` | `short` | `[{{instance}}]-[{{pod}}]-{{type}}-p95` |
| Write Stage P99 and Avg per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))`
`sum by(instance, pod, stage) (rate(greptime_mito_write_stage_elapsed_sum{instance=~"$datanode"}[$__rate_interval])) / sum by(instance, pod, stage) (rate(greptime_mito_write_stage_elapsed_count{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Write Stage P99 and average per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
| Cached Bytes per Instance | `greptime_mito_cache_bytes{instance=~"$datanode"}` | `timeseries` | Cached Bytes per Instance. | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
| Region Worker Handle Bulk Insert Requests | `histogram_quantile(0.95, sum by(le,instance, stage, pod) (rate(greptime_region_worker_handle_write_bucket[$__rate_interval])))`
`sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_sum[$__rate_interval]))/sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_count[$__rate_interval]))` | `timeseries` | Per-stage elapsed time for region worker to handle bulk insert region requests. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-P95` |
diff --git a/grafana/dashboards/metrics/cluster/dashboard.yaml b/grafana/dashboards/metrics/cluster/dashboard.yaml
index 7513c5e50e1..01fdb7bbc31 100644
--- a/grafana/dashboards/metrics/cluster/dashboard.yaml
+++ b/grafana/dashboards/metrics/cluster/dashboard.yaml
@@ -1279,6 +1279,26 @@ groups:
type: prometheus
uid: ${metrics}
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-avg'
+ - title: Scan Max Concurrent Files per Instance
+ type: timeseries
+ description: Estimated maximum concurrent files by instance and type (query or compaction). Query samples are region scan limit evaluations, including memtable sources counted by the limit, rejected scans, and scans using memory budgeting. Compaction samples count all input files when building a compaction reader. A SQL query can produce multiple region scan evaluations. P95/P99 are histogram estimates, not exact per-query maxima or live open-file counts.
+ unit: short
+ queries:
+ - expr: histogram_quantile(0.95, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket{instance=~"$datanode"}[$__rate_interval])))
+ datasource:
+ type: prometheus
+ uid: ${metrics}
+ legendFormat: '[{{instance}}]-[{{pod}}]-{{type}}-p95'
+ - expr: histogram_quantile(0.99, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket{instance=~"$datanode"}[$__rate_interval])))
+ datasource:
+ type: prometheus
+ uid: ${metrics}
+ legendFormat: '[{{instance}}]-[{{pod}}]-{{type}}-p99'
+ - expr: sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_sum{instance=~"$datanode"}[$__rate_interval])) / sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_count{instance=~"$datanode"}[$__rate_interval]))
+ datasource:
+ type: prometheus
+ uid: ${metrics}
+ legendFormat: '[{{instance}}]-[{{pod}}]-{{type}}-avg'
- title: Write Stage P99 and Avg per Instance
type: timeseries
description: Write Stage P99 and average per Instance.
diff --git a/grafana/dashboards/metrics/standalone/dashboard.json b/grafana/dashboards/metrics/standalone/dashboard.json
index f17d40b4f96..d980fb500d6 100644
--- a/grafana/dashboards/metrics/standalone/dashboard.json
+++ b/grafana/dashboards/metrics/standalone/dashboard.json
@@ -9112,6 +9112,132 @@
"title": "Read Stage P99 and Avg per Instance",
"type": "timeseries"
},
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "description": "Estimated maximum concurrent files by instance and type (query or compaction). Query samples are region scan limit evaluations, including memtable sources counted by the limit, rejected scans, and scans using memory budgeting. Compaction samples count all input files when building a compaction reader. A SQL query can produce multiple region scan evaluations. P95/P99 are histogram estimates, not exact per-query maxima or live open-file counts.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green"
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "short",
+ "min": 0
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 8,
+ "x": 8,
+ "y": 154
+ },
+ "id": 565,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "hideZeros": false,
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "pluginVersion": "11.6.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.95, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{instance}}]-[{{pod}}]-{{type}}-p95",
+ "range": true,
+ "refId": "A"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{instance}}]-[{{pod}}]-{{type}}-p99",
+ "range": true,
+ "refId": "B"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${metrics}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_sum[$__rate_interval])) / sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_count[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{instance}}]-[{{pod}}]-{{type}}-avg",
+ "range": true,
+ "refId": "C"
+ }
+ ],
+ "title": "Scan Max Concurrent Files per Instance",
+ "type": "timeseries"
+ },
{
"datasource": {
"type": "prometheus",
@@ -9176,7 +9302,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 8,
+ "x": 16,
"y": 154
},
"id": 490,
@@ -9292,8 +9418,8 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 16,
- "y": 154
+ "x": 0,
+ "y": 162
},
"id": 495,
"options": {
@@ -9391,7 +9517,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 0,
+ "x": 8,
"y": 162
},
"id": 501,
@@ -9505,7 +9631,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 8,
+ "x": 16,
"y": 162
},
"id": 502,
@@ -9619,8 +9745,8 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 16,
- "y": 162
+ "x": 0,
+ "y": 170
},
"id": 503,
"options": {
@@ -9736,7 +9862,7 @@
"gridPos": {
"h": 8,
"w": 8,
- "x": 0,
+ "x": 8,
"y": 170
},
"id": 504,
diff --git a/grafana/dashboards/metrics/standalone/dashboard.md b/grafana/dashboards/metrics/standalone/dashboard.md
index 5c7a4042444..7ed99d2ab2c 100644
--- a/grafana/dashboards/metrics/standalone/dashboard.md
+++ b/grafana/dashboards/metrics/standalone/dashboard.md
@@ -104,6 +104,7 @@
| Write Rows per Instance | `sum by (instance, pod) (rate(greptime_mito_write_rows_total[$__rate_interval]))` | `timeseries` | Ingestion size by row counts. | `prometheus` | `rowsps` | `[{{instance}}]-[{{pod}}]` |
| Read Stage OPS per Instance | `sum by(instance, pod) (rate(greptime_mito_read_stage_elapsed_count{stage="total"}[$__rate_interval]))` | `timeseries` | Read Stage OPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]` |
| Read Stage P99 and Avg per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket[$__rate_interval])))`
`sum by(instance, pod, stage) (rate(greptime_mito_read_stage_elapsed_sum[$__rate_interval])) / sum by(instance, pod, stage) (rate(greptime_mito_read_stage_elapsed_count[$__rate_interval]))` | `timeseries` | Read Stage P99 and average per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
+| Scan Max Concurrent Files per Instance | `histogram_quantile(0.95, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket[$__rate_interval])))`
`histogram_quantile(0.99, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket[$__rate_interval])))`
`sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_sum[$__rate_interval])) / sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_count[$__rate_interval]))` | `timeseries` | Estimated maximum concurrent files by instance and type (query or compaction). Query samples are region scan limit evaluations, including memtable sources counted by the limit, rejected scans, and scans using memory budgeting. Compaction samples count all input files when building a compaction reader. A SQL query can produce multiple region scan evaluations. P95/P99 are histogram estimates, not exact per-query maxima or live open-file counts. | `prometheus` | `short` | `[{{instance}}]-[{{pod}}]-{{type}}-p95` |
| Write Stage P99 and Avg per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket[$__rate_interval])))`
`sum by(instance, pod, stage) (rate(greptime_mito_write_stage_elapsed_sum[$__rate_interval])) / sum by(instance, pod, stage) (rate(greptime_mito_write_stage_elapsed_count[$__rate_interval]))` | `timeseries` | Write Stage P99 and average per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
| Cached Bytes per Instance | `greptime_mito_cache_bytes` | `timeseries` | Cached Bytes per Instance. | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
| Region Worker Handle Bulk Insert Requests | `histogram_quantile(0.95, sum by(le,instance, stage, pod) (rate(greptime_region_worker_handle_write_bucket[$__rate_interval])))`
`sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_sum[$__rate_interval]))/sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_count[$__rate_interval]))` | `timeseries` | Per-stage elapsed time for region worker to handle bulk insert region requests. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-P95` |
diff --git a/grafana/dashboards/metrics/standalone/dashboard.yaml b/grafana/dashboards/metrics/standalone/dashboard.yaml
index 627cd8b5d63..7f70dba0364 100644
--- a/grafana/dashboards/metrics/standalone/dashboard.yaml
+++ b/grafana/dashboards/metrics/standalone/dashboard.yaml
@@ -1279,6 +1279,26 @@ groups:
type: prometheus
uid: ${metrics}
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-avg'
+ - title: Scan Max Concurrent Files per Instance
+ type: timeseries
+ description: Estimated maximum concurrent files by instance and type (query or compaction). Query samples are region scan limit evaluations, including memtable sources counted by the limit, rejected scans, and scans using memory budgeting. Compaction samples count all input files when building a compaction reader. A SQL query can produce multiple region scan evaluations. P95/P99 are histogram estimates, not exact per-query maxima or live open-file counts.
+ unit: short
+ queries:
+ - expr: histogram_quantile(0.95, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket[$__rate_interval])))
+ datasource:
+ type: prometheus
+ uid: ${metrics}
+ legendFormat: '[{{instance}}]-[{{pod}}]-{{type}}-p95'
+ - expr: histogram_quantile(0.99, sum by(instance, pod, type, le) (rate(greptime_mito_scan_max_concurrent_files_bucket[$__rate_interval])))
+ datasource:
+ type: prometheus
+ uid: ${metrics}
+ legendFormat: '[{{instance}}]-[{{pod}}]-{{type}}-p99'
+ - expr: sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_sum[$__rate_interval])) / sum by(instance, pod, type) (rate(greptime_mito_scan_max_concurrent_files_count[$__rate_interval]))
+ datasource:
+ type: prometheus
+ uid: ${metrics}
+ legendFormat: '[{{instance}}]-[{{pod}}]-{{type}}-avg'
- title: Write Stage P99 and Avg per Instance
type: timeseries
description: Write Stage P99 and average per Instance.
diff --git a/src/mito2/src/metrics.rs b/src/mito2/src/metrics.rs
index cd1116c4fbd..cffa6de39a1 100644
--- a/src/mito2/src/metrics.rs
+++ b/src/mito2/src/metrics.rs
@@ -230,6 +230,14 @@ lazy_static! {
"Number of SSTs to scan in a scan task",
vec![1.0, 4.0, 8.0, 16.0, 32.0, 64.0, 256.0, 1024.0],
).unwrap();
+ /// Planned maximum concurrent sources per query scan limit evaluation or compaction reader.
+ /// Includes memtables counted by the file limit, rejected scans, and memory-budgeted scans.
+ pub static ref SCAN_MAX_CONCURRENT_FILES: HistogramVec = register_histogram_vec!(
+ "greptime_mito_scan_max_concurrent_files",
+ "Estimated maximum concurrent files (including memtable sources) per query scan limit evaluation or compaction reader",
+ &[TYPE_LABEL],
+ vec![0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 384.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0],
+ ).unwrap();
/// Histogram for the number of rows returned per query.
pub static ref READ_ROWS_RETURN: Histogram = register_histogram!(
"greptime_mito_read_rows_return",
diff --git a/src/mito2/src/read/seq_scan.rs b/src/mito2/src/read/seq_scan.rs
index 8db83ed1845..42119135805 100644
--- a/src/mito2/src/read/seq_scan.rs
+++ b/src/mito2/src/read/seq_scan.rs
@@ -36,6 +36,7 @@ use store_api::storage::TimeSeriesRowSelector;
use tokio::sync::Semaphore;
use crate::error::{PartitionOutOfRangeSnafu, Result, TooManyFilesToReadSnafu};
+use crate::metrics::SCAN_MAX_CONCURRENT_FILES;
use crate::read::flat_dedup::{FlatDedupReader, FlatLastNonNull, FlatLastRow};
use crate::read::flat_merge::FlatMergeReader;
use crate::read::last_row::FlatLastRowReader;
@@ -148,6 +149,11 @@ impl SeqScan {
pub(crate) async fn build_flat_reader_for_compaction(&self) -> Result {
assert!(self.stream_ctx.input.compaction);
+ // Compaction merges all input files together instead of scanning ranges sequentially.
+ SCAN_MAX_CONCURRENT_FILES
+ .with_label_values(&["compaction"])
+ .observe(self.stream_ctx.input.num_files() as f64);
+
let metrics_set = ExecutionPlanMetricsSet::new();
let part_metrics = self.new_partition_metrics(false, &metrics_set, 0);
debug_assert_eq!(1, self.properties.partitions.len());
@@ -526,9 +532,6 @@ impl SeqScan {
/// Checks resource limit for the scanner.
pub(crate) fn check_scan_limit(&self) -> Result<()> {
- if self.stream_ctx.input.uses_scan_memory_limit() {
- return Ok(());
- }
// Check max file count limit for all partitions since we scan them in parallel.
let total_max_files: usize = self
.properties
@@ -537,6 +540,15 @@ impl SeqScan {
.map(|partition| Self::max_files_in_partition(&self.stream_ctx.ranges, partition))
.sum();
+ if !self.stream_ctx.input.compaction {
+ SCAN_MAX_CONCURRENT_FILES
+ .with_label_values(&["query"])
+ .observe(total_max_files as f64);
+ }
+ if self.stream_ctx.input.uses_scan_memory_limit() {
+ return Ok(());
+ }
+
let max_concurrent_files = self.stream_ctx.input.max_concurrent_scan_files;
if total_max_files > max_concurrent_files {
return TooManyFilesToReadSnafu {
diff --git a/src/mito2/src/read/series_scan.rs b/src/mito2/src/read/series_scan.rs
index 64d5ceb07f8..f8af9e51b91 100644
--- a/src/mito2/src/read/series_scan.rs
+++ b/src/mito2/src/read/series_scan.rs
@@ -46,6 +46,7 @@ use crate::error::{
Error, InvalidSenderSnafu, JoinSnafu, PartitionOutOfRangeSnafu, Result, ScanMultiTimesSnafu,
ScanSeriesSnafu, TooManyFilesToReadSnafu,
};
+use crate::metrics::SCAN_MAX_CONCURRENT_FILES;
use crate::read::ScannerMetrics;
use crate::read::pruner::{PartitionPruner, Pruner, PrunerOptions};
use crate::read::scan_region::{ScanInput, StreamContext};
@@ -480,9 +481,6 @@ impl SeriesScan {
/// Checks resource limit for the scanner.
pub(crate) fn check_scan_limit(&self) -> Result<()> {
- if self.stream_ctx.input.uses_scan_memory_limit() {
- return Ok(());
- }
// Sum the total number of files across all partitions
let total_files: usize = self
.properties
@@ -495,6 +493,15 @@ impl SeriesScan {
})
.sum();
+ if !self.stream_ctx.input.compaction {
+ SCAN_MAX_CONCURRENT_FILES
+ .with_label_values(&["query"])
+ .observe(total_files as f64);
+ }
+ if self.stream_ctx.input.uses_scan_memory_limit() {
+ return Ok(());
+ }
+
let max_concurrent_files = self.stream_ctx.input.max_concurrent_scan_files;
if total_files > max_concurrent_files {
return TooManyFilesToReadSnafu {