From 80fc3fda07e1434f334b1e5a5e825ba235ef44e9 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 5 Jan 2022 16:00:11 +0200 Subject: [PATCH] lib/storage: follow-up for 38bf5fc1362922aa2dbcd5f81fa7442211a99c3c --- docs/CHANGELOG.md | 1 + lib/storage/index_db.go | 6 ++++-- lib/storage/tag_filters.go | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c51f39403..ce575ac64 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,6 +13,7 @@ sort: 15 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): make sure that `vmagent` replicas scrape the same targets at different time offsets when [replication is enabled in vmagent clustering mode](https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets). This guarantees that the [deduplication](https://docs.victoriametrics.com/#deduplication) consistently leaves samples from the same `vmagent` replica. * BUGFIX: return the proper response stub from `/api/v1/query_exemplars` handler, which is needed for Grafana v8+. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1999). * BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): fix a few edge cases and improve migration speed for OpenTSDB importer. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2019). +* BUGFIX: fix possible data race when searching for time series matching `{key=~"value|"}` filter. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2032). Thanks to @waldoweng for the provided fix. ## [v1.71.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.71.0) diff --git a/lib/storage/index_db.go b/lib/storage/index_db.go index 544777646..0b8e5b2f7 100644 --- a/lib/storage/index_db.go +++ b/lib/storage/index_db.go @@ -2744,9 +2744,11 @@ func (is *indexSearch) getMetricIDsForDateTagFilter(tf *tagFilter, date uint64, // Use global search if date isn't set. kb.B = is.marshalCommonPrefix(kb.B[:0], nsPrefixTagToMetricIDs) } + prefix := kb.B + kb.B = append(kb.B, tf.prefix[len(commonPrefix):]...) tfNew := *tf tfNew.isNegative = false // isNegative for the original tf is handled by the caller. - tfNew.prefix = append(kb.B, tf.prefix[len(commonPrefix):]...) + tfNew.prefix = kb.B metricIDs, loopsCount, err := is.getMetricIDsForTagFilter(&tfNew, maxMetrics, maxLoopsCount) if err != nil { return nil, loopsCount, err @@ -2760,7 +2762,7 @@ func (is *indexSearch) getMetricIDsForDateTagFilter(tf *tagFilter, date uint64, // See also https://github.com/VictoriaMetrics/VictoriaMetrics/issues/395 maxLoopsCount -= loopsCount tfNew = tagFilter{} - if err := tfNew.Init(kb.B, tf.key, []byte(".+"), false, true); err != nil { + if err := tfNew.Init(prefix, tf.key, []byte(".+"), false, true); err != nil { logger.Panicf(`BUG: cannot init tag filter: {%q=~".+"}: %s`, tf.key, err) } m, lc, err := is.getMetricIDsForTagFilter(&tfNew, maxMetrics, maxLoopsCount) diff --git a/lib/storage/tag_filters.go b/lib/storage/tag_filters.go index 72df2c049..60345a584 100644 --- a/lib/storage/tag_filters.go +++ b/lib/storage/tag_filters.go @@ -246,7 +246,7 @@ type tagFilter struct { // contains the prefix for regexp filter if isRegexp==true. regexpPrefix string - // Prefix always contains {nsPrefixTagToMetricIDs, AccountID, ProjectID, key}. + // Prefix contains either {nsPrefixTagToMetricIDs, AccountID, ProjectID, key} or {nsPrefixDateTagToMetricIDs, AccountID, ProjectID, date, key}. // Additionally it contains: // - value if !isRegexp. // - regexpPrefix if isRegexp. @@ -391,6 +391,8 @@ func getCommonPrefix(ss []string) (string, []string) { // Init initializes the tag filter for the given commonPrefix, key and value. // +// commonPrefix must contain either {nsPrefixTagToMetricIDs, AccountID, ProjectID} or {nsPrefixDateTagToMetricIDs, AccountID, ProjectID, date}. +// // If isNegaitve is true, then the tag filter matches all the values // except the given one. //