Repository: VictoriaMetrics/VictoriaMetrics
Pull request #2783 (2022-06-24 13:32:41)

vmalert: make `__name__` available for templating in alerts
Signed-off-by: hagen1778 <roman@victoriametrics.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) Report
> Merging [#2783](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) (0143d33) into [master](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/commit/bb7f31541fdd17442e4fcbcb8e8ae196868b89b2?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) (bb7f315) will **increase** coverage by `0.01%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##           master    #2783      +/-   ##
==========================================
+ Coverage   59.61%   59.62%   +0.01%     
==========================================
  Files         257      257              
  Lines       43895    43895              
==========================================
+ Hits        26166    26173       +7     
+ Misses      15992    15987       -5     
+ Partials     1737     1735       -2     
```


| [Impacted Files](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) | Coverage Δ | |
|---|---|---|
| [app/vmalert/alerting.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvYWxlcnRpbmcuZ28=) | `77.88% <100.00%> (ø)` | |
| [lib/storage/storage.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-bGliL3N0b3JhZ2Uvc3RvcmFnZS5nbw==) | `69.00% <0.00%> (-0.29%)` | :arrow_down: |
| [app/vmselect/promql/transform.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC90cmFuc2Zvcm0uZ28=) | `86.74% <0.00%> (-0.18%)` | :arrow_down: |
| [lib/storage/partition.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-bGliL3N0b3JhZ2UvcGFydGl0aW9uLmdv) | `64.02% <0.00%> (+0.15%)` | :arrow_up: |
| [lib/mergeset/table.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-bGliL21lcmdlc2V0L3RhYmxlLmdv) | `65.77% <0.00%> (+0.47%)` | :arrow_up: |
| [app/vmselect/promql/aggr\_incremental.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9hZ2dyX2luY3JlbWVudGFsLmdv) | `86.44% <0.00%> (+2.40%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics). Last update [bb7f315...0143d33](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/2783?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).


Patch:
diff --git a/app/vmalert/alerting.go b/app/vmalert/alerting.go
index 3f629dab4..7cfe1076a 100644
--- a/app/vmalert/alerting.go
+++ b/app/vmalert/alerting.go
@@ -159,11 +159,11 @@ func (ar *AlertingRule) toLabels(m datasource.Metric, qFn templates.QueryFn) (*l
 		processed: make(map[string]string),
 	}
 	for _, l := range m.Labels {
+		ls.origin[l.Name] = l.Value
 		// drop __name__ to be consistent with Prometheus alerting
 		if l.Name == "__name__" {
 			continue
 		}
-		ls.origin[l.Name] = l.Value
 		ls.processed[l.Name] = l.Value
 	}
 
diff --git a/app/vmalert/tpl/footer.qtpl b/app/vmalert/tpl/footer.qtpl
index 25327f5ef..ce86df8c8 100644
--- a/app/vmalert/tpl/footer.qtpl
+++ b/app/vmalert/tpl/footer.qtpl
@@ -1,7 +1,7 @@
 {% func Footer() %}
         </main>
-        <script src="static/js/jquery-3.6.0.min.js" type="text/javascript"></script>
-        <script src="static/js/bootstrap.bundle.min.js" type="text/javascript"></script>
+        <script src="/static/js/jquery-3.6.0.min.js" type="text/javascript"></script>
+        <script src="/static/js/bootstrap.bundle.min.js" type="text/javascript"></script>
         <script type="text/javascript">
             function expandAll() {
                $('.collapse').addClass('show');
diff --git a/app/vmalert/tpl/footer.qtpl.go b/app/vmalert/tpl/footer.qtpl.go
index 9f5a29c30..baaaab67f 100644
--- a/app/vmalert/tpl/footer.qtpl.go
+++ b/app/vmalert/tpl/footer.qtpl.go
@@ -22,8 +22,8 @@ func StreamFooter(qw422016 *qt422016.Writer) {
 //line app/vmalert/tpl/footer.qtpl:1
 	qw422016.N().S(`
         </main>
-        <script src="static/js/jquery-3.6.0.min.js" type="text/javascript"></script>
-        <script src="static/js/bootstrap.bundle.min.js" type="text/javascript"></script>
+        <script src="/static/js/jquery-3.6.0.min.js" type="text/javascript"></script>
+        <script src="/static/js/bootstrap.bundle.min.js" type="text/javascript"></script>
         <script type="text/javascript">
             function expandAll() {
                $('.collapse').addClass('show');
diff --git a/app/vmalert/tpl/header.qtpl b/app/vmalert/tpl/header.qtpl
index 486521268..9333ee192 100644
--- a/app/vmalert/tpl/header.qtpl
+++ b/app/vmalert/tpl/header.qtpl
@@ -3,7 +3,7 @@
 <html lang="en">
 <head>
     <title>vmalert{% if title != "" %} - {%s title %}{% endif %}</title>
-    <link href="static/css/bootstrap.min.css" rel="stylesheet" />
+    <link href="/static/css/bootstrap.min.css" rel="stylesheet" />
     <style>
         body{
           min-height: 75rem;
diff --git a/app/vmalert/tpl/header.qtpl.go b/app/vmalert/tpl/header.qtpl.go
index 09f05906f..23191d60b 100644
--- a/app/vmalert/tpl/header.qtpl.go
+++ b/app/vmalert/tpl/header.qtpl.go
@@ -35,7 +35,7 @@ func StreamHeader(qw422016 *qt422016.Writer, title string, pages []NavItem) {
 	}
 //line app/vmalert/tpl/header.qtpl:5
 	qw422016.N().S(`</title>
-    <link href="static/css/bootstrap.min.css" rel="stylesheet" />
+    <link href="/static/css/bootstrap.min.css" rel="stylesheet" />
     <style>
         body{
           min-height: 75rem;
diff --git a/app/vmselect/graphite/metrics_api.go b/app/vmselect/graphite/metrics_api.go
index a95fa8104..c83fc9648 100644
--- a/app/vmselect/graphite/metrics_api.go
+++ b/app/vmselect/graphite/metrics_api.go
@@ -198,7 +198,7 @@ func MetricsIndexHandler(startTime time.Time, w http.ResponseWriter, r *http.Req
 	deadline := searchutils.GetDeadlineForQuery(r, startTime)
 	jsonp := r.FormValue("jsonp")
 	sq := storage.NewSearchQuery(0, 0, nil, 0)
-	metricNames, err := netstorage.GetLabelValues(nil, "__name__", sq, 0, deadline)
+	metricNames, err := netstorage.LabelValues(nil, "__name__", sq, 0, deadline)
 	if err != nil {
 		return fmt.Errorf(`cannot obtain metric names: %w`, err)
 	}
@@ -219,7 +219,7 @@ func metricsFind(tr storage.TimeRange, label, qHead, qTail string, delimiter byt
 	n := strings.IndexAny(qTail, "*{[")
 	if n < 0 {
 		query := qHead + qTail
-		suffixes, err := netstorage.GetTagValueSuffixes(nil, tr, label, query, delimiter, deadline)
+		suffixes, err := netstorage.TagValueSuffixes(nil, tr, label, query, delimiter, deadline)
 		if err != nil {
 			return nil, err
 		}
@@ -239,7 +239,7 @@ func metricsFind(tr storage.TimeRange, label, qHead, qTail string, delimiter byt
 	}
 	if n == len(qTail)-1 && strings.HasSuffix(qTail, "*") {
 		query := qHead + qTail[:len(qTail)-1]
-		suffixes, err := netstorage.GetTagValueSuffixes(nil, tr, label, query, delimiter, deadline)
+		suffixes, err := netstorage.TagValueSuffixes(nil, tr, label, query, delimiter, deadline)
 		if err != nil {
 			return nil, err
 		}
diff --git a/app/vmselect/graphite/tags_api.go b/app/vmselect/graphite/tags_api.go
index 9cb78d8c9..2606ec063 100644
--- a/app/vmselect/graphite/tags_api.go
+++ b/app/vmselect/graphite/tags_api.go
@@ -178,11 +178,11 @@ func TagsAutoCompleteValuesHandler(startTime time.Time, w http.ResponseWriter, r
 		return fmt.Errorf("cannot setup tag filters: %w", err)
 	}
 	if len(exprs) == 0 && len(etfs) == 0 {
-		// Fast path: there are no `expr` filters, so use netstorage.GetGraphiteTagValues.
+		// Fast path: there are no `expr` filters, so use netstorage.GraphiteTagValues.
 		// Escape special chars in tagPrefix as Graphite does.
 		// See https://github.com/graphite-project/graphite-web/blob/3ad279df5cb90b211953e39161df416e54a84948/webapp/graphite/tags/base.py#L228
 		filter := regexp.QuoteMeta(valuePrefix)
-		tagValues, err = netstorage.GetGraphiteTagValues(nil, tag, filter, limit, deadline)
+		tagValues, err = netstorage.GraphiteTagValues(nil, tag, filter, limit, deadline)
 		if err != nil {
 			return err
 		}
@@ -260,12 +260,12 @@ func TagsAutoCompleteTagsHandler(startTime time.Time, w http.ResponseWriter, r *
 		return fmt.Errorf("cannot setup tag filters: %w", err)
 	}
 	if len(exprs) == 0 && len(etfs) == 0 {
-		// Fast path: there are no `expr` filters, so use netstorage.GetGraphiteTags.
+		// Fast path: there are no `expr` filters, so use netstorage.GraphiteTags.
 
 		// Escape special chars in tagPrefix as Graphite does.
 		// See https://github.com/graphite-project/graphite-web/blob/3ad279df5cb90b211953e39161df416e54a84948/webapp/graphite/tags/base.py#L181
 		filter := regexp.QuoteMeta(tagPrefix)
-		labels, err = netstorage.GetGraphiteTags(nil, filter, limit, deadline)
+		labels, err = netstorage.GraphiteTags(nil, filter, limit, deadline)
 		if err != nil {
 			return err
 		}
@@ -396,7 +396,7 @@ func TagValuesHandler(startTime time.Time, tagName string, w http.ResponseWriter
 		return err
 	}
 	filter := r.FormValue("filter")
-	tagValues, err := netstorage.GetGraphiteTagValues(nil, tagName, filter, limit, deadline)
+	tagValues, err := netstorage.GraphiteTagValues(nil, tagName, filter, limit, deadline)
 	if err != nil {
 		return err
 	}
@@ -424,7 +424,7 @@ func TagsHandler(startTime time.Time, w http.ResponseWriter, r *http.Request) er
 		return err
 	}
 	filter := r.FormValue("filter")
-	labels, err := netstorage.GetGraphiteTags(nil, filter, limit, deadline)
+	labels, err := netstorage.GraphiteTags(nil, filter, limit, deadline)
 	if err != nil {
 		return err
 	}
diff --git a/app/vmselect/netstorage/netstorage.go b/app/vmselect/netstorage/netstorage.go
index 88ae27f67..25d1c2524 100644
--- a/app/vmselect/netstorage/netstorage.go
+++ b/app/vmselect/netstorage/netstorage.go
@@ -611,8 +611,8 @@ func DeleteSeries(qt *querytracer.Tracer, sq *storage.SearchQuery, deadline sear
 	return vmstorage.DeleteMetrics(tfss)
 }
 
-// GetLabelNames returns label names matching the given sq until the given deadline.
-func GetLabelNames(qt *querytracer.Tracer, sq *storage.SearchQuery, maxLabelNames int, deadline searchutils.Deadline) ([]string, error) {
+// LabelNames returns label names matching the given sq until the given deadline.
+func LabelNames(qt *querytracer.Tracer, sq *storage.SearchQuery, maxLabelNames int, deadline searchutils.Deadline) ([]string, error) {
 	qt = qt.NewChild("get labels: %s", sq)
 	defer qt.Done()
 	if deadline.Exceeded() {
@@ -639,15 +639,15 @@ func GetLabelNames(qt *querytracer.Tracer, sq *storage.SearchQuery, maxLabelName
 	return labels, nil
 }
 
-// GetGraphiteTags returns Graphite tags until the given deadline.
-func GetGraphiteTags(qt *querytracer.Tracer, filter string, limit int, deadline searchutils.Deadline) ([]string, error) {
+// GraphiteTags returns Graphite tags until the given deadline.
+func GraphiteTags(qt *querytracer.Tracer, filter string, limit int, deadline searchutils.Deadline) ([]string, error) {
 	qt = qt.NewChild("get graphite tags: filter=%s, limit=%d", filter, limit)
 	defer qt.Done()
 	if deadline.Exceeded() {
 		return nil, fmt.Errorf("timeout exceeded before starting the query processing: %s", deadline.String())
 	}
 	sq := storage.NewSearchQuery(0, 0, nil, 0)
-	labels, err := GetLabelNames(qt, sq, 0, deadline)
+	labels, err := LabelNames(qt, sq, 0, deadline)
 	if err != nil {
 		return nil, err
 	}
@@ -687,8 +687,8 @@ func hasString(a []string, s string) bool {
 	return false
 }
 
-// GetLabelValues returns label values matching the given labelName and sq until the given deadline.
-func GetLabelValues(qt *querytracer.Tracer, labelName string, sq *storage.SearchQuery, maxLabelValues int, deadline searchutils.Deadline) ([]string, error) {
+// LabelValues returns label values matching the given labelName and sq until the given deadline.
+func LabelValues(qt *querytracer.Tracer, labelName string, sq *storage.SearchQuery, maxLabelValues int, deadline searchutils.Deadline) ([]string, error) {
 	qt = qt.NewChild("get values for label %s: %s", labelName, sq)
 	defer qt.Done()
 	if deadline.Exceeded() {
@@ -715,8 +715,8 @@ func GetLabelValues(qt *querytracer.Tracer, labelName string, sq *storage.Search
 	return labelValues, nil
 }
 
-// GetGraphiteTagValues returns tag values for the given tagName until the given deadline.
-func GetGraphiteTagValues(qt *querytracer.Tracer, tagName, filter string, limit int, deadline searchutils.Deadline) ([]string, error) {
+// GraphiteTagValues returns tag values for the given tagName until the given deadline.
+func GraphiteTagValues(qt *querytracer.Tracer, tagName, filter string, limit int, deadline searchutils.Deadline) ([]string, error) {
 	qt = qt.NewChild("get graphite tag values for tagName=%s, filter=%s, limit=%d", tagName, filter, limit)
 	defer qt.Done()
 	if deadline.Exceeded() {
@@ -726,7 +726,7 @@ func GetGraphiteTagValues(qt *querytracer.Tracer, tagName, filter string, limit
 		tagName = ""
 	}
 	sq := storage.NewSearchQuery(0, 0, nil, 0)
-	tagValues, err := GetLabelValues(qt, tagName, sq, 0, deadline)
+	tagValues, err := LabelValues(qt, tagName, sq, 0, deadline)
 	if err != nil {
 		return nil, err
 	}
@@ -742,10 +742,10 @@ func GetGraphiteTagValues(qt *querytracer.Tracer, tagName, filter string, limit
 	return tagValues, nil
 }
 
-// GetTagValueSuffixes returns tag value suffixes for the given tagKey and the given tagValuePrefix.
+// TagValueSuffixes returns tag value suffixes for the given tagKey and the given tagValuePrefix.
 //
 // It can be used for implementing https://graphite-api.readthedocs.io/en/latest/api.html#metrics-find
-func GetTagValueSuffixes(qt *querytracer.Tracer, tr storage.TimeRange, tagKey, tagValuePrefix string, delimiter byte, deadline searchutils.Deadline) ([]string, error) {
+func TagValueSuffixes(qt *querytracer.Tracer, tr storage.TimeRange, tagKey, tagValuePrefix string, delimiter byte, deadline searchutils.Deadline) ([]string, error) {
 	qt = qt.NewChild("get tag value suffixes for tagKey=%s, tagValuePrefix=%s, timeRange=%s", tagKey, tagValuePrefix, &tr)
 	defer qt.Done()
 	if deadline.Exceeded() {
@@ -764,10 +764,10 @@ func GetTagValueSuffixes(qt *querytracer.Tracer, tr storage.TimeRange, tagKey, t
 	return suffixes, nil
 }
 
-// GetTSDBStatus returns tsdb status according to https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-stats
+// TSDBStatus returns tsdb status according to https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-stats
 //
 // It accepts aribtrary filters on time series in sq.
-func GetTSDBStatus(qt *querytracer.Tracer, sq *storage.SearchQuery, focusLabel string, topN int, deadline searchutils.Deadline) (*storage.TSDBStatus, error) {
+func TSDBStatus(qt *querytracer.Tracer, sq *storage.SearchQuery, focusLabel string, topN int, deadline searchutils.Deadline) (*storage.TSDBStatus, error) {
 	qt = qt.NewChild("get tsdb stats: %s, focusLabel=%q, topN=%d", sq, focusLabel, topN)
 	defer qt.Done()
 	if deadline.Exceeded() {
@@ -789,8 +789,8 @@ func GetTSDBStatus(qt *querytracer.Tracer, sq *storage.SearchQuery, focusLabel s
 	return status, nil
 }
 
-// GetSeriesCount returns the number of unique series.
-func GetSeriesCount(qt *querytracer.Tracer, deadline searchutils.Deadline) (uint64, error) {
+// SeriesCount returns the number of unique series.
+func SeriesCount(qt *querytracer.Tracer, deadline searchutils.Deadline) (uint64, error) {
 	qt = qt.NewChild("get series count")
 	defer qt.Done()
 	if deadline.Exceeded() {
diff --git a/app/vmselect/prometheus/prometheus.go b/app/vmselect/prometheus/prometheus.go
index b30bdc304..bacf01780 100644
--- a/app/vmselect/prometheus/prometheus.go
+++ b/app/vmselect/prometheus/prometheus.go
@@ -456,7 +456,7 @@ func LabelValuesHandler(qt *querytracer.Tracer, startTime time.Time, labelName s
 		return err
 	}
 	sq := storage.NewSearchQuery(cp.start, cp.end, cp.filterss, *maxUniqueTimeseries)
-	labelValues, err := netstorage.GetLabelValues(qt, labelName, sq, limit, cp.deadline)
+	labelValues, err := netstorage.LabelValues(qt, labelName, sq, limit, cp.deadline)
 	if err != nil {
 		return fmt.Errorf("cannot obtain values for label %q: %w", labelName, err)
 	}
@@ -521,7 +521,7 @@ func TSDBStatusHandler(qt *querytracer.Tracer, startTime time.Time, w http.Respo
 	start := int64(date*secsPerDay) * 1000
 	end := int64((date+1)*secsPerDay)*1000 - 1
 	sq := storage.NewSearchQuery(start, end, cp.filterss, *maxTSDBStatusSeries)
-	status, err := netstorage.GetTSDBStatus(qt, sq, focusLabel, topN, cp.deadline)
+	status, err := netstorage.TSDBStatus(qt, sq, focusLabel, topN, cp.deadline)
 	if err != nil {
 		return fmt.Errorf("cannot obtain tsdb stats: %w", err)
 	}
@@ -553,7 +553,7 @@ func LabelsHandler(qt *querytracer.Tracer, startTime time.Time, w http.ResponseW
 		return err
 	}
 	sq := storage.NewSearchQuery(cp.start, cp.end, cp.filterss, *maxUniqueTimeseries)
-	labels, err := netstorage.GetLabelNames(qt, sq, limit, cp.deadline)
+	labels, err := netstorage.LabelNames(qt, sq, limit, cp.deadline)
 	if err != nil {
 		return fmt.Errorf("cannot obtain labels: %w", err)
 	}
@@ -575,7 +575,7 @@ func SeriesCountHandler(startTime time.Time, w http.ResponseWriter, r *http.Requ
 	defer seriesCountDuration.UpdateDuration(startTime)
 
 	deadline := searchutils.GetDeadlineForStatusRequest(r, startTime)
-	n, err := netstorage.GetSeriesCount(nil, deadline)
+	n, err := netstorage.SeriesCount(nil, deadline)
 	if err != nil {
 		return fmt.Errorf("cannot obtain series count: %w", err)
 	}
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 4dbfc397d..f5025d308 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -15,9 +15,12 @@ The following tip changes can be tested by building VictoriaMetrics components f
 
 ## tip
 
+**Update notes:** this release introduces backwards-incompatible changes to `vm_partial_results_total` metric by changing its labels to be consistent with `vm_requests_total` metric.
+If you use alerting rules or Grafana dashboards, which rely on this metric, then they must be updated. The official dashboards for VictoriaMetrics don't use this metric.
+
 * FEATURE: add `-search.setLookbackToStep` command-line flag, which enables InfluxDB-like gap filling during querying. See [these docs](https://docs.victoriametrics.com/guides/migrate-from-influx.html) for details.
-* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add ability to specify additional HTTP headers to send to scrape targets via `headers` section in `scrape_configs`. This can be used when the scrape target requires custom authorization and authentication like in [this stackoverflow question](https://stackoverflow.com/questions/66032498/prometheus-scrape-metric-with-custom-header). For example, the following config instructs sending `My-Auth: top-secret` and `TenantID: FooBar` headers with each request to `http://host123:8080/metrics`:
 * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add an UI for [query tracing](https://docs.victoriametrics.com/#query-tracing). It can be enabled by clicking `enable query tracing` checkbox and re-running the query. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2703).
+* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add ability to specify additional HTTP headers to send to scrape targets via `headers` section in `scrape_configs`. This can be used when the scrape target requires custom authorization and authentication like in [this stackoverflow question](https://stackoverflow.com/questions/66032498/prometheus-scrape-metric-with-custom-header). For example, the following config instructs sending `My-Auth: top-secret` and `TenantID: FooBar` headers with each request to `http://host123:8080/metrics`:
 
 ```yaml
 scrape_configs:
@@ -29,8 +32,10 @@ scrape_configs:
   - targets: ["host123:8080"]
 ```
 
+* BUGFIX: limit max memory occupied by the cache, which stores parsed regular expressions. Previously too long regular expressions passed in [MetricsQL queries](https://docs.victoriametrics.com/MetricsQL.html) could result in big amounts of used memory (e.g. multiple of gigabytes). Now the max cache size for parsed regexps is limited to a a few megabytes.
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): make sure that [stale markers](https://docs.victoriametrics.com/vmagent.html#prometheus-staleness-markers) are generated with the actual timestamp when unsuccessful scrape occurs. This should prevent from possible time series overlap on scrape target restart in dynmaic envirnoments such as Kubernetes.
 * BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): assume that the response is complete if `-search.denyPartialResponse` is enabled and up to `-replicationFactor - 1` `vmstorage` nodes are unavailable. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1767).
+* BUGFIX: [vmselect](https://docs.victoriametrics.com/#vmselect): update `vm_partial_results_total` metric labels to be consistent with `vm_requests_total` labels.
 
 ## [v1.78.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.78.0)
 
diff --git a/go.mod b/go.mod
index 5e7bcba43..a575c7bf6 100644
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,7 @@ require (
 	// like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b
 	github.com/VictoriaMetrics/fasthttp v1.1.0
 	github.com/VictoriaMetrics/metrics v1.18.1
-	github.com/VictoriaMetrics/metricsql v0.43.0
+	github.com/VictoriaMetrics/metricsql v0.44.0
 	github.com/aws/aws-sdk-go v1.44.37
 	github.com/cespare/xxhash/v2 v2.1.2
 
diff --git a/go.sum b/go.sum
index a43e7544a..2432b16ee 100644
--- a/go.sum
+++ b/go.sum
@@ -107,8 +107,8 @@ github.com/VictoriaMetrics/fasthttp v1.1.0 h1:3crd4YWHsMwu60GUXRH6OstowiFvqrwS4a
 github.com/VictoriaMetrics/fasthttp v1.1.0/go.mod h1:/7DMcogqd+aaD3G3Hg5kFgoFwlR2uydjiWvoLp5ZTqQ=
 github.com/VictoriaMetrics/metrics v1.18.1 h1:OZ0+kTTto8oPfHnVAnTOoyl0XlRhRkoQrD2n2cOuRw0=
 github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA=
-github.com/VictoriaMetrics/metricsql v0.43.0 h1:pFkzfExn9GJ1w3tE1pFTkjlyPd4kr/onh5CBAJAZf+s=
-github.com/VictoriaMetrics/metricsql v0.43.0/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0=
+github.com/VictoriaMetrics/metricsql v0.44.0 h1:zxBVeg9tbm6zl2ft2Ica87ItUWYey02hy3MN2ti1ljg=
+github.com/VictoriaMetrics/metricsql v0.44.0/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0=
 github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
 github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
diff --git a/vendor/github.com/VictoriaMetrics/metricsql/regexp_cache.go b/vendor/github.com/VictoriaMetrics/metricsql/regexp_cache.go
index 327a6dfed..d41e1fc08 100644
--- a/vendor/github.com/VictoriaMetrics/metricsql/regexp_cache.go
+++ b/vendor/github.com/VictoriaMetrics/metricsql/regexp_cache.go
@@ -29,10 +29,14 @@ func CompileRegexp(re string) (*regexp.Regexp, error) {
 	return rcv.r, rcv.err
 }
 
+// regexpCacheCharsMax limits the max number of chars stored in regexp cache across all entries.
+//
+// We limit by number of chars since calculating the exact size of each regexp is problematic,
+// while using chars seems like universal approach for short and long regexps.
+const regexpCacheCharsMax = 1e6
+
 var regexpCacheV = func() *regexpCache {
-	rc := &regexpCache{
-		m: make(map[string]*regexpCacheValue),
-	}
+	rc := newRegexpCache(regexpCacheCharsMax)
 	metrics.NewGauge(`vm_cache_requests_total{type="promql/regexp"}`, func() float64 {
 		return float64(rc.Requests())
 	})
@@ -42,27 +46,51 @@ var regexpCacheV = func() *regexpCache {
 	metrics.NewGauge(`vm_cache_entries{type="promql/regexp"}`, func() float64 {
 		return float64(rc.Len())
 	})
+	metrics.NewGauge(`vm_cache_chars_current{type="promql/regexp"}`, func() float64 {
+		return float64(rc.CharsCurrent())
+	})
+	metrics.NewGauge(`vm_cache_chars_max{type="promql/regexp"}`, func() float64 {
+		return float64(rc.charsLimit)
+	})
 	return rc
 }()
 
-const regexpCacheMaxLen = 10e3
-
 type regexpCacheValue struct {
 	r   *regexp.Regexp
 	err error
 }
 
+func (rcv *regexpCacheValue) RegexpLen() int {
+	if r := rcv.r; r != nil {
+		return len(r.String())
+	}
+	return len(rcv.err.Error())
+}
+
 type regexpCache struct {
 	// Move atomic counters to the top of struct for 8-byte alignment on 32-bit arch.
 	// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/212
-
 	requests uint64
 	misses   uint64
 
+	// charsCurrent stores the total number of characters used in stored regexps.
+	// is used for memory usage estimation.
+	charsCurrent int
+
+	// charsLimit is the maximum number of chars the regexpCache can store.
+	charsLimit int
+
 	m  map[string]*regexpCacheValue
 	mu sync.RWMutex
 }
 
+func newRegexpCache(charsLimit int) *regexpCache {
+	return &regexpCache{
+		m:          make(map[string]*regexpCacheValue),
+		charsLimit: charsLimit,
+	}
+}
+
 func (rc *regexpCache) Requests() uint64 {
 	return atomic.LoadUint64(&rc.requests)
 }
@@ -71,11 +99,18 @@ func (rc *regexpCache) Misses() uint64 {
 	return atomic.LoadUint64(&rc.misses)
 }
 
-func (rc *regexpCache) Len() uint64 {
+func (rc *regexpCache) Len() int {
 	rc.mu.RLock()
 	n := len(rc.m)
 	rc.mu.RUnlock()
-	return uint64(n)
+	return n
+}
+
+func (rc *regexpCache) CharsCurrent() int {
+	rc.mu.RLock()
+	n := rc.charsCurrent
+	rc.mu.RUnlock()
+	return int(n)
 }
 
 func (rc *regexpCache) Get(regexp string) *regexpCacheValue {
@@ -93,18 +128,22 @@ func (rc *regexpCache) Get(regexp string) *regexpCacheValue {
 
 func (rc *regexpCache) Put(regexp string, rcv *regexpCacheValue) {
 	rc.mu.Lock()
-	overflow := len(rc.m) - regexpCacheMaxLen
-	if overflow > 0 {
-		// Remove 10% of items from the cache.
-		overflow = int(float64(len(rc.m)) * 0.1)
-		for k := range rc.m {
+	if rc.charsCurrent > rc.charsLimit {
+		// Remove items accounting for 10% chars from the cache.
+		overflow := int(float64(rc.charsLimit) * 0.1)
+		for k, v := range rc.m {
 			delete(rc.m, k)
-			overflow--
+
+			size := len(k) + v.RegexpLen()
+			overflow -= size
+			rc.charsCurrent -= size
+
 			if overflow <= 0 {
 				break
 			}
 		}
 	}
 	rc.m[regexp] = rcv
+	rc.charsCurrent += len(regexp) + rcv.RegexpLen()
 	rc.mu.Unlock()
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 2b87ef92b..f76d20b22 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -27,7 +27,7 @@ github.com/VictoriaMetrics/fasthttp/stackless
 # github.com/VictoriaMetrics/metrics v1.18.1
 ## explicit; go 1.12
 github.com/VictoriaMetrics/metrics
-# github.com/VictoriaMetrics/metricsql v0.43.0
+# github.com/VictoriaMetrics/metricsql v0.44.0
 ## explicit; go 1.13
 github.com/VictoriaMetrics/metricsql
 github.com/VictoriaMetrics/metricsql/binaryop


Test patch:
diff --git a/app/vmalert/alerting_test.go b/app/vmalert/alerting_test.go
index ab5be6392..2e4c231ed 100644
--- a/app/vmalert/alerting_test.go
+++ b/app/vmalert/alerting_test.go
@@ -731,14 +731,14 @@ func TestAlertingRule_Template(t *testing.T) {
 					"instance": "{{ $labels.instance }}",
 				},
 				Annotations: map[string]string{
-					"summary":     `Too high connection number for "{{ $labels.instance }}"`,
+					"summary":     `{{ $labels.__name__ }}: Too high connection number for "{{ $labels.instance }}"`,
 					"description": `{{ $labels.alertname}}: It is {{ $value }} connections for "{{ $labels.instance }}"`,
 				},
 				alerts: make(map[uint64]*notifier.Alert),
 			},
 			[]datasource.Metric{
-				metricWithValueAndLabels(t, 2, "instance", "foo", alertNameLabel, "override"),
-				metricWithValueAndLabels(t, 10, "instance", "bar", alertNameLabel, "override"),
+				metricWithValueAndLabels(t, 2, "__name__", "first", "instance", "foo", alertNameLabel, "override"),
+				metricWithValueAndLabels(t, 10, "__name__", "second", "instance", "bar", alertNameLabel, "override"),
 			},
 			map[uint64]*notifier.Alert{
 				hash(map[string]string{alertNameLabel: "override label", "instance": "foo"}): {
@@ -747,7 +747,7 @@ func TestAlertingRule_Template(t *testing.T) {
 						"instance":     "foo",
 					},
 					Annotations: map[string]string{
-						"summary":     `Too high connection number for "foo"`,
+						"summary":     `first: Too high connection number for "foo"`,
 						"description": `override: It is 2 connections for "foo"`,
 					},
 				},
@@ -757,7 +757,7 @@ func TestAlertingRule_Template(t *testing.T) {
 						"instance":     "bar",
 					},
 					Annotations: map[string]string{
-						"summary":     `Too high connection number for "bar"`,
+						"summary":     `second: Too high connection number for "bar"`,
 						"description": `override: It is 10 connections for "bar"`,
 					},
 				},