Repository: VictoriaMetrics/VictoriaMetrics
Pull request #4468 (2023-06-19 16:13:31)

Docs/backfiling: adds curl commands to clear the query cache

hagen1778: bump @denisgolius 

Patch:
diff --git a/Makefile b/Makefile
index 0d50b29b8..a5d1c2393 100644
--- a/Makefile
+++ b/Makefile
@@ -478,16 +478,18 @@ check-licenses: install-wwhrd
 	wwhrd check -f .wwhrd.yml
 
 copy-docs:
+# The 'printf' function is used instead of 'echo' or 'echo -e' to handle line breaks (e.g. '\n') in the same way on different operating systems (MacOS/Ubuntu Linux/Arch Linux) and their shells (bash/sh/zsh/fish).
+# For details, see https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4548#issue-1782796419 and https://stackoverflow.com/questions/8467424/echo-newline-in-bash-prints-literal-n
 	echo "---" > ${DST}
 	@if [ ${ORDER} -ne 0 ]; then \
 		echo "sort: ${ORDER}" >> ${DST}; \
 		echo "weight: ${ORDER}" >> ${DST}; \
-		echo "menu:\n  docs:\n    parent: 'victoriametrics'\n    weight: ${ORDER}" >> ${DST}; \
+		printf "menu:\n  docs:\n    parent: 'victoriametrics'\n    weight: ${ORDER}\n" >> ${DST}; \
 	fi
 
 	echo "title: ${TITLE}" >> ${DST}
 	@if [ ${OLD_URL} ]; then \
-		echo "aliases:\n  - ${OLD_URL}" >> ${DST}; \
+		printf "aliases:\n  - ${OLD_URL}\n" >> ${DST}; \
 	fi
 	echo "---" >> ${DST}
 	cat ${SRC} >> ${DST}
diff --git a/README.md b/README.md
index eb15671fc..3edb338e5 100644
--- a/README.md
+++ b/README.md
@@ -16,14 +16,14 @@ VictoriaMetrics is a fast, cost-effective and scalable monitoring solution and t
 VictoriaMetrics is available in [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases),
 [Docker images](https://hub.docker.com/r/victoriametrics/victoria-metrics/), [Snap packages](https://snapcraft.io/victoriametrics)
 and [source code](https://github.com/VictoriaMetrics/VictoriaMetrics). 
-Just download [the latest version of VictoriaMetrics](https://docs.victoriametrics.com/CHANGELOG.html)
-and follow [these instructions](https://docs.victoriametrics.com/Quick-Start.html).
 
 The cluster version of VictoriaMetrics is available [here](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html).
 
 Learn more about [key concepts](https://docs.victoriametrics.com/keyConcepts.html) of VictoriaMetrics and follow the 
 [quick start guide](https://docs.victoriametrics.com/Quick-Start.html) for a better experience.
 
+There is also user-friendly database for logs - [VictoriaLogs](https://docs.victoriametrics.com/VictoriaLogs/).
+
 If you have questions about VictoriaMetrics, then feel free asking them at [VictoriaMetrics community Slack chat](https://slack.victoriametrics.com/).
 
 [Contact us](mailto:info@victoriametrics.com) if you need enterprise support for VictoriaMetrics. 
@@ -118,6 +118,7 @@ Case studies:
 * [MHI Vestas Offshore Wind](https://docs.victoriametrics.com/CaseStudies.html#mhi-vestas-offshore-wind)
 * [Razorpay](https://docs.victoriametrics.com/CaseStudies.html#razorpay)
 * [Percona](https://docs.victoriametrics.com/CaseStudies.html#percona)
+* [Roblox](https://docs.victoriametrics.com/CaseStudies.html#roblox)
 * [Sensedia](https://docs.victoriametrics.com/CaseStudies.html#sensedia)
 * [Smarkets](https://docs.victoriametrics.com/CaseStudies.html#smarkets)
 * [Synthesio](https://docs.victoriametrics.com/CaseStudies.html#synthesio)
@@ -1578,19 +1579,22 @@ See also [how to work with snapshots](#how-to-work-with-snapshots).
 
 ## Retention
 
-Retention is configured with the `-retentionPeriod` command-line flag, which takes a number followed by a time unit character - `h(ours)`, `d(ays)`, `w(eeks)`, `y(ears)`. If the time unit is not specified, a month is assumed. For instance, `-retentionPeriod=3` means that the data will be stored for 3 months and then deleted. The default retention period is one month. The minimum retention period is 24h or 1d.
+Retention is configured with the `-retentionPeriod` command-line flag, which takes a number followed by a time unit 
+character - `h(ours)`, `d(ays)`, `w(eeks)`, `y(ears)`. If the time unit is not specified, a month is assumed. 
+For instance, `-retentionPeriod=3` means that the data will be stored for 3 months and then deleted. 
+The default retention period is one month. The **minimum retention** period is 24h or 1d.
 
 Data is split in per-month partitions inside `<-storageDataPath>/data/{small,big}` folders.
-Data partitions outside the configured retention are deleted on the first day of the new month.
-Each partition consists of one or more data parts. Data parts outside the configured retention are eventually deleted during
-[background merge](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282).
+**Data partitions** outside the configured retention are deleted **on the first day of the new month**.
+Each partition consists of one or more **data parts**. Data parts outside the configured retention 
+are **eventually deleted** during [background merge](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282).
+The time range covered by data part is **not limited by retention period unit**. One data part can cover hours or days of 
+data. Hence, a data part can be deleted only **when fully outside the configured retention**.
+See more about partitions and parts [here](#storage).
 
 The maximum disk space usage for a given `-retentionPeriod` is going to be (`-retentionPeriod` + 1) months.
 For example, if `-retentionPeriod` is set to 1, data for January is deleted on March 1st.
 
-Please note, the time range covered by data part is not limited by retention period unit. Hence, data part may contain data
-for multiple days and will be deleted only when fully outside the configured retention.
-
 It is safe to extend `-retentionPeriod` on existing data. If `-retentionPeriod` is set to a lower
 value than before, then data outside the configured period will be eventually deleted.
 
@@ -2056,8 +2060,7 @@ It is recommended disabling query cache with `-search.disableCache` command-line
 historical data with timestamps from the past, since the cache assumes that the data is written with
 the current timestamps. Query cache can be enabled after the backfilling is complete.
 
-An alternative solution is to query `/internal/resetRollupResultCache` url after backfilling is complete. This will reset
-the query cache, which could contain incomplete data cached during the backfilling.
+An alternative solution is to query [/internal/resetRollupResultCache](https://docs.victoriametrics.com/url-examples.html#internalresetRollupResultCache) handler after the backfilling is complete. This will reset the query cache, which could contain incomplete data cached during the backfilling.
 
 Yet another solution is to increase `-search.cacheTimestampOffset` flag value in order to disable caching
 for data with timestamps close to the current time. Single-node VictoriaMetrics automatically resets response
diff --git a/app/vmagent/remotewrite/client.go b/app/vmagent/remotewrite/client.go
index 3a19cca8e..36add0c3f 100644
--- a/app/vmagent/remotewrite/client.go
+++ b/app/vmagent/remotewrite/client.go
@@ -257,7 +257,7 @@ func getAuthConfig(argIdx int) (*promauth.Config, error) {
 	}
 	authCfg, err := opts.NewConfig()
 	if err != nil {
-		return nil, fmt.Errorf("cannot populate OAuth2 config for remoteWrite idx: %d, err: %w", argIdx, err)
+		return nil, fmt.Errorf("cannot populate auth config for remoteWrite idx: %d, err: %w", argIdx, err)
 	}
 	return authCfg, nil
 }
diff --git a/app/vmalert/main.go b/app/vmalert/main.go
index 0762cc634..912daefa4 100644
--- a/app/vmalert/main.go
+++ b/app/vmalert/main.go
@@ -8,6 +8,7 @@ import (
 	"os"
 	"strconv"
 	"strings"
+	"sync"
 	"time"
 
 	"github.com/VictoriaMetrics/metrics"
@@ -326,8 +327,7 @@ func configReload(ctx context.Context, m *manager, groupsCfg []config.Group, sig
 	}
 
 	// init reload metrics with positive values to improve alerting conditions
-	configSuccess.Set(1)
-	configTimestamp.Set(fasttime.UnixTimestamp())
+	setConfigSuccess(fasttime.UnixTimestamp())
 	parseFn := config.Parse
 	for {
 		select {
@@ -347,22 +347,19 @@ func configReload(ctx context.Context, m *manager, groupsCfg []config.Group, sig
 			parseFn = config.ParseSilent
 		}
 		if err := notifier.Reload(); err != nil {
-			configReloadErrors.Inc()
-			configSuccess.Set(0)
+			setConfigError(err)
 			logger.Errorf("failed to reload notifier config: %s", err)
 			continue
 		}
 		err := templates.Load(*ruleTemplatesPath, false)
 		if err != nil {
-			configReloadErrors.Inc()
-			configSuccess.Set(0)
+			setConfigError(err)
 			logger.Errorf("failed to load new templates: %s", err)
 			continue
 		}
 		newGroupsCfg, err := parseFn(*rulePath, validateTplFn, *validateExpressions)
 		if err != nil {
-			configReloadErrors.Inc()
-			configSuccess.Set(0)
+			setConfigError(err)
 			logger.Errorf("cannot parse configuration file: %s", err)
 			continue
 		}
@@ -371,19 +368,18 @@ func configReload(ctx context.Context, m *manager, groupsCfg []config.Group, sig
 			// set success to 1 since previous reload
 			// could have been unsuccessful
 			configSuccess.Set(1)
+			setConfigError(nil)
 			// config didn't change - skip it
 			continue
 		}
 		if err := m.update(ctx, newGroupsCfg, false); err != nil {
-			configReloadErrors.Inc()
-			configSuccess.Set(0)
+			setConfigError(err)
 			logger.Errorf("error while reloading rules: %s", err)
 			continue
 		}
 		templates.Reload()
 		groupsCfg = newGroupsCfg
-		configSuccess.Set(1)
-		configTimestamp.Set(fasttime.UnixTimestamp())
+		setConfigSuccess(fasttime.UnixTimestamp())
 		logger.Infof("Rules reloaded successfully from %q", *rulePath)
 	}
 }
@@ -399,3 +395,40 @@ func configsEqual(a, b []config.Group) bool {
 	}
 	return true
 }
+
+// setConfigSuccess sets config reload status to 1.
+func setConfigSuccess(at uint64) {
+	configSuccess.Set(1)
+	configTimestamp.Set(fasttime.UnixTimestamp())
+	// reset the error if any
+	setConfigErr(nil)
+}
+
+// setConfigError sets config reload status to 0.
+func setConfigError(err error) {
+	configReloadErrors.Inc()
+	configSuccess.Set(0)
+	setConfigErr(err)
+}
+
+var (
+	configErrMu sync.RWMutex
+	// configErr represent the error message from the last
+	// config reload.
+	configErr error
+)
+
+func setConfigErr(err error) {
+	configErrMu.Lock()
+	configErr = err
+	configErrMu.Unlock()
+}
+
+func configError() error {
+	configErrMu.RLock()
+	defer configErrMu.RUnlock()
+	if configErr != nil {
+		return configErr
+	}
+	return nil
+}
diff --git a/app/vmalert/static/js/custom.js b/app/vmalert/static/js/custom.js
index 8e06ca2a7..5a1f7f2e7 100644
--- a/app/vmalert/static/js/custom.js
+++ b/app/vmalert/static/js/custom.js
@@ -7,9 +7,11 @@ function collapseAll() {
 }
 
 function toggleByID(id) {
-    let el = $("#" + id);
-    if (el.length > 0) {
-        el.click();
+    if (id) {
+        let el = $("#" + id);
+        if (el.length > 0) {
+            el.click();
+        }
     }
 }
 
@@ -36,4 +38,4 @@ $(document).ready(function () {
 
 $(document).ready(function () {
     $('[data-bs-toggle="tooltip"]').tooltip();
-});
\ No newline at end of file
+});
diff --git a/app/vmalert/tpl/header.qtpl b/app/vmalert/tpl/header.qtpl
index d08ae138c..e2c6b0fd5 100644
--- a/app/vmalert/tpl/header.qtpl
+++ b/app/vmalert/tpl/header.qtpl
@@ -6,8 +6,8 @@
     "github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
 ) %}
 
-{% func Header(r *http.Request, navItems []NavItem, title string) %}
-    {%code prefix := utils.Prefix(r.URL.Path) %}
+{% func Header(r *http.Request, navItems []NavItem, title string, userErr error) %}
+{%code prefix := utils.Prefix(r.URL.Path) %}
 <!DOCTYPE html>
 <html lang="en">
 <head>
@@ -70,8 +70,9 @@
     </style>
 </head>
 <body>
-    {%= printNavItems(r, title, navItems) %}
+    {%= printNavItems(r, title, navItems, userErr) %}
     <main class="px-2">
+    {%= errorBody(userErr) %}
 {% endfunc %}
 
 
@@ -82,7 +83,7 @@ type NavItem struct {
 }
 %}
 
-{% func printNavItems(r *http.Request, current string, items []NavItem) %}
+{% func printNavItems(r *http.Request, current string, items []NavItem, userErr error) %}
 {%code
     prefix := utils.Prefix(r.URL.Path)
 %}
@@ -103,5 +104,30 @@ type NavItem struct {
             {% endfor %}
         </ul>
   </div>
+  {%= errorIcon(userErr) %}
 </nav>
 {% endfunc %}
+
+{% func errorIcon(err error) %}
+{% if err != nil %}
+<div class="d-flex" data-bs-toggle="tooltip" data-bs-placement="left" title="Configuration file failed to reload! Click to see more details.">
+  <a type="button" data-bs-toggle="collapse" href="#reload-groups-error">
+      <span class="text-danger">
+          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-exclamation-triangle-fill" viewBox="0 0 16 16">
+              <path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
+          </svg>
+      </span>
+  </a>
+</div>
+{% endif %}
+{% endfunc %}
+
+{% func errorBody(err error) %}
+{% if err != nil %}
+<div class="collapse mt-2 mb-2" id="reload-groups-error">
+  <div class="card card-body">
+    {%s err.Error() %}
+  </div>
+</div>
+{% endif %}
+{% endfunc %}
diff --git a/app/vmalert/tpl/header.qtpl.go b/app/vmalert/tpl/header.qtpl.go
index 0d0b46a49..424e17ace 100644
--- a/app/vmalert/tpl/header.qtpl.go
+++ b/app/vmalert/tpl/header.qtpl.go
@@ -27,10 +27,10 @@ var (
 )
 
 //line app/vmalert/tpl/header.qtpl:9
-func StreamHeader(qw422016 *qt422016.Writer, r *http.Request, navItems []NavItem, title string) {
+func StreamHeader(qw422016 *qt422016.Writer, r *http.Request, navItems []NavItem, title string, userErr error) {
 //line app/vmalert/tpl/header.qtpl:9
 	qw422016.N().S(`
-    `)
+`)
 //line app/vmalert/tpl/header.qtpl:10
 	prefix := utils.Prefix(r.URL.Path)
 
@@ -114,135 +114,251 @@ func StreamHeader(qw422016 *qt422016.Writer, r *http.Request, navItems []NavItem
 <body>
     `)
 //line app/vmalert/tpl/header.qtpl:73
-	streamprintNavItems(qw422016, r, title, navItems)
+	streamprintNavItems(qw422016, r, title, navItems, userErr)
 //line app/vmalert/tpl/header.qtpl:73
 	qw422016.N().S(`
     <main class="px-2">
-`)
+    `)
 //line app/vmalert/tpl/header.qtpl:75
+	streamerrorBody(qw422016, userErr)
+//line app/vmalert/tpl/header.qtpl:75
+	qw422016.N().S(`
+`)
+//line app/vmalert/tpl/header.qtpl:76
 }
 
-//line app/vmalert/tpl/header.qtpl:75
-func WriteHeader(qq422016 qtio422016.Writer, r *http.Request, navItems []NavItem, title string) {
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
+func WriteHeader(qq422016 qtio422016.Writer, r *http.Request, navItems []NavItem, title string, userErr error) {
+//line app/vmalert/tpl/header.qtpl:76
 	qw422016 := qt422016.AcquireWriter(qq422016)
-//line app/vmalert/tpl/header.qtpl:75
-	StreamHeader(qw422016, r, navItems, title)
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
+	StreamHeader(qw422016, r, navItems, title, userErr)
+//line app/vmalert/tpl/header.qtpl:76
 	qt422016.ReleaseWriter(qw422016)
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
 }
 
-//line app/vmalert/tpl/header.qtpl:75
-func Header(r *http.Request, navItems []NavItem, title string) string {
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
+func Header(r *http.Request, navItems []NavItem, title string, userErr error) string {
+//line app/vmalert/tpl/header.qtpl:76
 	qb422016 := qt422016.AcquireByteBuffer()
-//line app/vmalert/tpl/header.qtpl:75
-	WriteHeader(qb422016, r, navItems, title)
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
+	WriteHeader(qb422016, r, navItems, title, userErr)
+//line app/vmalert/tpl/header.qtpl:76
 	qs422016 := string(qb422016.B)
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
 	qt422016.ReleaseByteBuffer(qb422016)
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
 	return qs422016
-//line app/vmalert/tpl/header.qtpl:75
+//line app/vmalert/tpl/header.qtpl:76
 }
 
-//line app/vmalert/tpl/header.qtpl:79
+//line app/vmalert/tpl/header.qtpl:80
 type NavItem struct {
 	Name string
 	Url  string
 }
 
-//line app/vmalert/tpl/header.qtpl:85
-func streamprintNavItems(qw422016 *qt422016.Writer, r *http.Request, current string, items []NavItem) {
-//line app/vmalert/tpl/header.qtpl:85
+//line app/vmalert/tpl/header.qtpl:86
+func streamprintNavItems(qw422016 *qt422016.Writer, r *http.Request, current string, items []NavItem, userErr error) {
+//line app/vmalert/tpl/header.qtpl:86
 	qw422016.N().S(`
 `)
-//line app/vmalert/tpl/header.qtpl:87
+//line app/vmalert/tpl/header.qtpl:88
 	prefix := utils.Prefix(r.URL.Path)
 
-//line app/vmalert/tpl/header.qtpl:88
+//line app/vmalert/tpl/header.qtpl:89
 	qw422016.N().S(`
 <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
   <div class="container-fluid">
     <div class="collapse navbar-collapse" id="navbarCollapse">
         <ul class="navbar-nav me-auto mb-2 mb-md-0">
             `)
-//line app/vmalert/tpl/header.qtpl:93
+//line app/vmalert/tpl/header.qtpl:94
 	for _, item := range items {
-//line app/vmalert/tpl/header.qtpl:93
+//line app/vmalert/tpl/header.qtpl:94
 		qw422016.N().S(`
                 <li class="nav-item">
                     `)
-//line app/vmalert/tpl/header.qtpl:96
+//line app/vmalert/tpl/header.qtpl:97
 		u, _ := url.Parse(item.Url)
 
-//line app/vmalert/tpl/header.qtpl:97
+//line app/vmalert/tpl/header.qtpl:98
 		qw422016.N().S(`
                     <a class="nav-link`)
-//line app/vmalert/tpl/header.qtpl:98
+//line app/vmalert/tpl/header.qtpl:99
 		if current == item.Name {
-//line app/vmalert/tpl/header.qtpl:98
+//line app/vmalert/tpl/header.qtpl:99
 			qw422016.N().S(` active`)
-//line app/vmalert/tpl/header.qtpl:98
+//line app/vmalert/tpl/header.qtpl:99
 		}
-//line app/vmalert/tpl/header.qtpl:98
+//line app/vmalert/tpl/header.qtpl:99
 		qw422016.N().S(`"
                        href="`)
-//line app/vmalert/tpl/header.qtpl:99
+//line app/vmalert/tpl/header.qtpl:100
 		if u.IsAbs() {
-//line app/vmalert/tpl/header.qtpl:99
+//line app/vmalert/tpl/header.qtpl:100
 			qw422016.E().S(item.Url)
-//line app/vmalert/tpl/header.qtpl:99
+//line app/vmalert/tpl/header.qtpl:100
 		} else {
-//line app/vmalert/tpl/header.qtpl:99
+//line app/vmalert/tpl/header.qtpl:100
 			qw422016.E().S(path.Join(prefix, item.Url))
-//line app/vmalert/tpl/header.qtpl:99
+//line app/vmalert/tpl/header.qtpl:100
 		}
-//line app/vmalert/tpl/header.qtpl:99
+//line app/vmalert/tpl/header.qtpl:100
 		qw422016.N().S(`">
                         `)
-//line app/vmalert/tpl/header.qtpl:100
+//line app/vmalert/tpl/header.qtpl:101
 		qw422016.E().S(item.Name)
-//line app/vmalert/tpl/header.qtpl:100
+//line app/vmalert/tpl/header.qtpl:101
 		qw422016.N().S(`
                     </a>
                 </li>
             `)
-//line app/vmalert/tpl/header.qtpl:103
+//line app/vmalert/tpl/header.qtpl:104
 	}
-//line app/vmalert/tpl/header.qtpl:103
+//line app/vmalert/tpl/header.qtpl:104
 	qw422016.N().S(`
         </ul>
   </div>
+  `)
+//line app/vmalert/tpl/header.qtpl:107
+	streamerrorIcon(qw422016, userErr)
+//line app/vmalert/tpl/header.qtpl:107
+	qw422016.N().S(`
 </nav>
 `)
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
 }
 
-//line app/vmalert/tpl/header.qtpl:107
-func writeprintNavItems(qq422016 qtio422016.Writer, r *http.Request, current string, items []NavItem) {
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
+func writeprintNavItems(qq422016 qtio422016.Writer, r *http.Request, current string, items []NavItem, userErr error) {
+//line app/vmalert/tpl/header.qtpl:109
 	qw422016 := qt422016.AcquireWriter(qq422016)
-//line app/vmalert/tpl/header.qtpl:107
-	streamprintNavItems(qw422016, r, current, items)
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
+	streamprintNavItems(qw422016, r, current, items, userErr)
+//line app/vmalert/tpl/header.qtpl:109
 	qt422016.ReleaseWriter(qw422016)
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
 }
 
-//line app/vmalert/tpl/header.qtpl:107
-func printNavItems(r *http.Request, current string, items []NavItem) string {
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
+func printNavItems(r *http.Request, current string, items []NavItem, userErr error) string {
+//line app/vmalert/tpl/header.qtpl:109
 	qb422016 := qt422016.AcquireByteBuffer()
-//line app/vmalert/tpl/header.qtpl:107
-	writeprintNavItems(qb422016, r, current, items)
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
+	writeprintNavItems(qb422016, r, current, items, userErr)
+//line app/vmalert/tpl/header.qtpl:109
 	qs422016 := string(qb422016.B)
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
 	qt422016.ReleaseByteBuffer(qb422016)
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
 	return qs422016
-//line app/vmalert/tpl/header.qtpl:107
+//line app/vmalert/tpl/header.qtpl:109
+}
+
+//line app/vmalert/tpl/header.qtpl:111
+func streamerrorIcon(qw422016 *qt422016.Writer, err error) {
+//line app/vmalert/tpl/header.qtpl:111
+	qw422016.N().S(`
+`)
+//line app/vmalert/tpl/header.qtpl:112
+	if err != nil {
+//line app/vmalert/tpl/header.qtpl:112
+		qw422016.N().S(`
+<div class="d-flex" data-bs-toggle="tooltip" data-bs-placement="left" title="Configuration file failed to reload! Click to see more details.">
+  <a type="button" data-bs-toggle="collapse" href="#reload-groups-error">
+      <span class="text-danger">
+          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-exclamation-triangle-fill" viewBox="0 0 16 16">
+              <path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
+          </svg>
+      </span>
+  </a>
+</div>
+`)
+//line app/vmalert/tpl/header.qtpl:122
+	}
+//line app/vmalert/tpl/header.qtpl:122
+	qw422016.N().S(`
+`)
+//line app/vmalert/tpl/header.qtpl:123
+}
+
+//line app/vmalert/tpl/header.qtpl:123
+func writeerrorIcon(qq422016 qtio422016.Writer, err error) {
+//line app/vmalert/tpl/header.qtpl:123
+	qw422016 := qt422016.AcquireWriter(qq422016)
+//line app/vmalert/tpl/header.qtpl:123
+	streamerrorIcon(qw422016, err)
+//line app/vmalert/tpl/header.qtpl:123
+	qt422016.ReleaseWriter(qw422016)
+//line app/vmalert/tpl/header.qtpl:123
+}
+
+//line app/vmalert/tpl/header.qtpl:123
+func errorIcon(err error) string {
+//line app/vmalert/tpl/header.qtpl:123
+	qb422016 := qt422016.AcquireByteBuffer()
+//line app/vmalert/tpl/header.qtpl:123
+	writeerrorIcon(qb422016, err)
+//line app/vmalert/tpl/header.qtpl:123
+	qs422016 := string(qb422016.B)
+//line app/vmalert/tpl/header.qtpl:123
+	qt422016.ReleaseByteBuffer(qb422016)
+//line app/vmalert/tpl/header.qtpl:123
+	return qs422016
+//line app/vmalert/tpl/header.qtpl:123
+}
+
+//line app/vmalert/tpl/header.qtpl:125
+func streamerrorBody(qw422016 *qt422016.Writer, err error) {
+//line app/vmalert/tpl/header.qtpl:125
+	qw422016.N().S(`
+`)
+//line app/vmalert/tpl/header.qtpl:126
+	if err != nil {
+//line app/vmalert/tpl/header.qtpl:126
+		qw422016.N().S(`
+<div class="collapse mt-2 mb-2" id="reload-groups-error">
+  <div class="card card-body">
+    `)
+//line app/vmalert/tpl/header.qtpl:129
+		qw422016.E().S(err.Error())
+//line app/vmalert/tpl/header.qtpl:129
+		qw422016.N().S(`
+  </div>
+</div>
+`)
+//line app/vmalert/tpl/header.qtpl:132
+	}
+//line app/vmalert/tpl/header.qtpl:132
+	qw422016.N().S(`
+`)
+//line app/vmalert/tpl/header.qtpl:133
+}
+
+//line app/vmalert/tpl/header.qtpl:133
+func writeerrorBody(qq422016 qtio422016.Writer, err error) {
+//line app/vmalert/tpl/header.qtpl:133
+	qw422016 := qt422016.AcquireWriter(qq422016)
+//line app/vmalert/tpl/header.qtpl:133
+	streamerrorBody(qw422016, err)
+//line app/vmalert/tpl/header.qtpl:133
+	qt422016.ReleaseWriter(qw422016)
+//line app/vmalert/tpl/header.qtpl:133
+}
+
+//line app/vmalert/tpl/header.qtpl:133
+func errorBody(err error) string {
+//line app/vmalert/tpl/header.qtpl:133
+	qb422016 := qt422016.AcquireByteBuffer()
+//line app/vmalert/tpl/header.qtpl:133
+	writeerrorBody(qb422016, err)
+//line app/vmalert/tpl/header.qtpl:133
+	qs422016 := string(qb422016.B)
+//line app/vmalert/tpl/header.qtpl:133
+	qt422016.ReleaseByteBuffer(qb422016)
+//line app/vmalert/tpl/header.qtpl:133
+	return qs422016
+//line app/vmalert/tpl/header.qtpl:133
 }
diff --git a/app/vmalert/web.qtpl b/app/vmalert/web.qtpl
index 55bc0e3e5..1b412c7c3 100644
--- a/app/vmalert/web.qtpl
+++ b/app/vmalert/web.qtpl
@@ -12,7 +12,7 @@
 
 
 {% func Welcome(r *http.Request) %}
-    {%= tpl.Header(r, navItems, "vmalert") %}
+    {%= tpl.Header(r, navItems, "vmalert", configError()) %}
     <p>
         API:<br>
         {% for _, p := range apiLinks  %}
@@ -40,7 +40,7 @@ btn-primary
 
 {% func ListGroups(r *http.Request, originGroups []APIGroup) %}
     {%code prefix := utils.Prefix(r.URL.Path) %}
-    {%= tpl.Header(r, navItems, "Groups") %}
+    {%= tpl.Header(r, navItems, "Groups", configError()) %}
         {%code
             filter := r.URL.Query().Get("filter")
             rOk := make(map[string]int)
@@ -164,7 +164,7 @@ btn-primary
 
 {% func ListAlerts(r *http.Request, groupAlerts []GroupAlerts) %}
     {%code prefix := utils.Prefix(r.URL.Path) %}
-    {%= tpl.Header(r, navItems, "Alerts") %}
+    {%= tpl.Header(r, navItems, "Alerts", configError()) %}
     {% if len(groupAlerts) > 0 %}
          <a class="btn btn-primary" role="button" onclick="collapseAll()">Collapse All</a>
          <a class="btn btn-primary" role="button" onclick="expandAll()">Expand All</a>
@@ -250,7 +250,7 @@ btn-primary
 {% endfunc %}
 
 {% func ListTargets(r *http.Request, targets map[notifier.TargetType][]notifier.Target) %}
-    {%= tpl.Header(r, navItems, "Notifiers") %}
+    {%= tpl.Header(r, navItems, "Notifiers", configError()) %}
     {% if len(targets) > 0 %}
          <a class="btn btn-primary" role="button" onclick="collapseAll()">Collapse All</a>
          <a class="btn btn-primary" role="button" onclick="expandAll()">Expand All</a>
@@ -307,7 +307,7 @@ btn-primary
 
 {% func Alert(r *http.Request, alert *APIAlert) %}
     {%code prefix := utils.Prefix(r.URL.Path) %}
-    {%= tpl.Header(r, navItems, "") %}
+    {%= tpl.Header(r, navItems, "", configError()) %}
     {%code
         var labelKeys []string
         for k := range alert.Labels {
@@ -394,7 +394,7 @@ btn-primary
 
 {% func RuleDetails(r *http.Request, rule APIRule) %}
     {%code prefix := utils.Prefix(r.URL.Path) %}
-    {%= tpl.Header(r, navItems, "") %}
+    {%= tpl.Header(r, navItems, "", configError()) %}
     {%code
         var labelKeys []string
         for k := range rule.Labels {
@@ -578,4 +578,4 @@ btn-primary
   func isNoMatch (r APIRule) bool {
     return r.LastSamples == 0 && r.LastSeriesFetched != nil && *r.LastSeriesFetched == 0
   }
-%}
\ No newline at end of file
+%}
diff --git a/app/vmalert/web.qtpl.go b/app/vmalert/web.qtpl.go
index 029bc8064..97999a74f 100644
--- a/app/vmalert/web.qtpl.go
+++ b/app/vmalert/web.qtpl.go
@@ -34,7 +34,7 @@ func StreamWelcome(qw422016 *qt422016.Writer, r *http.Request) {
 	qw422016.N().S(`
     `)
 //line app/vmalert/web.qtpl:15
-	tpl.StreamHeader(qw422016, r, navItems, "vmalert")
+	tpl.StreamHeader(qw422016, r, navItems, "vmalert", configError())
 //line app/vmalert/web.qtpl:15
 	qw422016.N().S(`
     <p>
@@ -207,7 +207,7 @@ func StreamListGroups(qw422016 *qt422016.Writer, r *http.Request, originGroups [
 	qw422016.N().S(`
     `)
 //line app/vmalert/web.qtpl:43
-	tpl.StreamHeader(qw422016, r, navItems, "Groups")
+	tpl.StreamHeader(qw422016, r, navItems, "Groups", configError())
 //line app/vmalert/web.qtpl:43
 	qw422016.N().S(`
         `)
@@ -619,7 +619,7 @@ func StreamListAlerts(qw422016 *qt422016.Writer, r *http.Request, groupAlerts []
 	qw422016.N().S(`
     `)
 //line app/vmalert/web.qtpl:167
-	tpl.StreamHeader(qw422016, r, navItems, "Alerts")
+	tpl.StreamHeader(qw422016, r, navItems, "Alerts", configError())
 //line app/vmalert/web.qtpl:167
 	qw422016.N().S(`
     `)
@@ -885,7 +885,7 @@ func StreamListTargets(qw422016 *qt422016.Writer, r *http.Request, targets map[n
 	qw422016.N().S(`
     `)
 //line app/vmalert/web.qtpl:253
-	tpl.StreamHeader(qw422016, r, navItems, "Notifiers")
+	tpl.StreamHeader(qw422016, r, navItems, "Notifiers", configError())
 //line app/vmalert/web.qtpl:253
 	qw422016.N().S(`
     `)
@@ -1065,7 +1065,7 @@ func StreamAlert(qw422016 *qt422016.Writer, r *http.Request, alert *APIAlert) {
 	qw422016.N().S(`
     `)
 //line app/vmalert/web.qtpl:310
-	tpl.StreamHeader(qw422016, r, navItems, "")
+	tpl.StreamHeader(qw422016, r, navItems, "", configError())
 //line app/vmalert/web.qtpl:310
 	qw422016.N().S(`
     `)
@@ -1274,7 +1274,7 @@ func StreamRuleDetails(qw422016 *qt422016.Writer, r *http.Request, rule APIRule)
 	qw422016.N().S(`
     `)
 //line app/vmalert/web.qtpl:397
-	tpl.StreamHeader(qw422016, r, navItems, "")
+	tpl.StreamHeader(qw422016, r, navItems, "", configError())
 //line app/vmalert/web.qtpl:397
 	qw422016.N().S(`
     `)
diff --git a/app/vmctl/influx/influx.go b/app/vmctl/influx/influx.go
index ab25bcb3f..32b5998c6 100644
--- a/app/vmctl/influx/influx.go
+++ b/app/vmctl/influx/influx.go
@@ -153,6 +153,10 @@ func (c *Client) Explore() ([]*Series, error) {
 		return nil, fmt.Errorf("failed to get field keys: %s", err)
 	}
 
+	if len(mFields) < 1 {
+		return nil, fmt.Errorf("found no numeric fields for import in database %q", c.database)
+	}
+
 	series, err := c.getSeries()
 	if err != nil {
 		return nil, fmt.Errorf("failed to get series: %s", err)
diff --git a/app/vmui/Dockerfile-web b/app/vmui/Dockerfile-web
index e446e29e0..19539efce 100644
--- a/app/vmui/Dockerfile-web
+++ b/app/vmui/Dockerfile-web
@@ -6,7 +6,7 @@ COPY web/ /build/
 RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o web-amd64 github.com/VictoriMetrics/vmui/ && \
     GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o web-windows github.com/VictoriMetrics/vmui/
 
-FROM alpine:3.18.0
+FROM alpine:3.18.2
 USER root
 
 COPY --from=build-web-stage /build/web-amd64 /app/web
diff --git a/deployment/docker/Makefile b/deployment/docker/Makefile
index b1392cbcf..2a417fc00 100644
--- a/deployment/docker/Makefile
+++ b/deployment/docker/Makefile
@@ -2,10 +2,10 @@
 
 DOCKER_NAMESPACE ?= victoriametrics
 
-ROOT_IMAGE ?= alpine:3.18.0
+ROOT_IMAGE ?= alpine:3.18.2
 
-# Use alpine:3.17.3 instead of 3.18.0 for CERTS_IMAGE
-# because alpine:3.18.0 is broken for cross-platform builds
+# Use alpine:3.17.3 instead of 3.18.2 for CERTS_IMAGE
+# because alpine:3.18.2 is broken for cross-platform builds
 # TODO: sync it with ROOT_IMAGE when it will be fixed in the new alpine releases
 CERTS_IMAGE := alpine:3.17.3
 
diff --git a/deployment/docker/docker-compose-cluster.yml b/deployment/docker/docker-compose-cluster.yml
index 89fdf9d4b..83cdf8a77 100644
--- a/deployment/docker/docker-compose-cluster.yml
+++ b/deployment/docker/docker-compose-cluster.yml
@@ -2,7 +2,7 @@ version: '3.5'
 services:
   vmagent:
     container_name: vmagent
-    image: victoriametrics/vmagent:v1.91.2
+    image: victoriametrics/vmagent:v1.91.3
     depends_on:
       - "vminsert"
     ports:
@@ -32,7 +32,7 @@ services:
 
   vmstorage-1:
     container_name: vmstorage-1
-    image: victoriametrics/vmstorage:v1.91.2-cluster
+    image: victoriametrics/vmstorage:v1.91.3-cluster
     ports:
       - 8482
       - 8400
@@ -44,7 +44,7 @@ services:
     restart: always
   vmstorage-2:
     container_name: vmstorage-2
-    image: victoriametrics/vmstorage:v1.91.2-cluster
+    image: victoriametrics/vmstorage:v1.91.3-cluster
     ports:
       - 8482
       - 8400
@@ -56,7 +56,7 @@ services:
     restart: always
   vminsert:
     container_name: vminsert
-    image: victoriametrics/vminsert:v1.91.2-cluster
+    image: victoriametrics/vminsert:v1.91.3-cluster
     depends_on:
       - "vmstorage-1"
       - "vmstorage-2"
@@ -68,7 +68,7 @@ services:
     restart: always
   vmselect:
     container_name: vmselect
-    image: victoriametrics/vmselect:v1.91.2-cluster
+    image: victoriametrics/vmselect:v1.91.3-cluster
     depends_on:
       - "vmstorage-1"
       - "vmstorage-2"
@@ -82,7 +82,7 @@ services:
 
   vmalert:
     container_name: vmalert
-    image: victoriametrics/vmalert:v1.91.2
+    image: victoriametrics/vmalert:v1.91.3
     depends_on:
       - "vmselect"
     ports:
diff --git a/deployment/docker/docker-compose.yml b/deployment/docker/docker-compose.yml
index a9e8189b7..eed8b2643 100644
--- a/deployment/docker/docker-compose.yml
+++ b/deployment/docker/docker-compose.yml
@@ -2,7 +2,7 @@ version: "3.5"
 services:
   vmagent:
     container_name: vmagent
-    image: victoriametrics/vmagent:v1.91.2
+    image: victoriametrics/vmagent:v1.91.3
     depends_on:
       - "victoriametrics"
     ports:
@@ -18,7 +18,7 @@ services:
     restart: always
   victoriametrics:
     container_name: victoriametrics
-    image: victoriametrics/victoria-metrics:v1.91.2
+    image: victoriametrics/victoria-metrics:v1.91.3
     ports:
       - 8428:8428
       - 8089:8089
@@ -56,7 +56,7 @@ services:
     restart: always
   vmalert:
     container_name: vmalert
-    image: victoriametrics/vmalert:v1.91.2
+    image: victoriametrics/vmalert:v1.91.3
     depends_on:
       - "victoriametrics"
       - "alertmanager"
diff --git a/deployment/logs-benchmark/docker-compose.yml b/deployment/logs-benchmark/docker-compose.yml
index 2365bec5b..8dd49648f 100644
--- a/deployment/logs-benchmark/docker-compose.yml
+++ b/deployment/logs-benchmark/docker-compose.yml
@@ -105,7 +105,7 @@ services:
       - '--config=/config.yml'
 
   vmsingle:
-    image: victoriametrics/victoria-metrics:v1.91.2
+    image: victoriametrics/victoria-metrics:v1.91.3
     ports:
       - '8428:8428'
     command:
diff --git a/deployment/marketplace/digitialocean/one-click-droplet/RELEASE_GUIDE.md b/deployment/marketplace/digitialocean/one-click-droplet/RELEASE_GUIDE.md
index f3c57cf56..f10e1a709 100644
--- a/deployment/marketplace/digitialocean/one-click-droplet/RELEASE_GUIDE.md
+++ b/deployment/marketplace/digitialocean/one-click-droplet/RELEASE_GUIDE.md
@@ -8,7 +8,7 @@
 4. Set variables `DIGITALOCEAN_API_TOKEN` with `VM_VERSION` for `packer` environment and run make from example below:
 
 ```console
-make release-victoria-metrics-digitalocean-oneclick-droplet DIGITALOCEAN_API_TOKEN="dop_v23_2e46f4759ceeeba0d0248" VM_VERSION="1.91.2"
+make release-victoria-metrics-digitalocean-oneclick-droplet DIGITALOCEAN_API_TOKEN="dop_v23_2e46f4759ceeeba0d0248" VM_VERSION="1.91.3"
 ```
 
 
diff --git a/deployment/marketplace/digitialocean/one-click-droplet/files/etc/update-motd.d/99-one-click b/deployment/marketplace/digitialocean/one-click-droplet/files/etc/update-motd.d/99-one-click
index af8b34c11..4b1a97726 100755
--- a/deployment/marketplace/digitialocean/one-click-droplet/files/etc/update-motd.d/99-one-click
+++ b/deployment/marketplace/digitialocean/one-click-droplet/files/etc/update-motd.d/99-one-click
@@ -19,8 +19,8 @@ On the server:
   * VictoriaMetrics is running on ports: 8428, 8089, 4242, 2003 and they are bound to the local interface.
 
 ********************************************************************************
-  # This image includes 1.91.2 version of VictoriaMetrics.
-  # See Release notes https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.91.2
+  # This image includes 1.91.3 version of VictoriaMetrics.
+  # See Release notes https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.91.3
 
   # Welcome to VictoriaMetrics droplet!
 
diff --git a/docs/Articles.md b/docs/Articles.md
index abf00eb64..1c070e6cc 100644
--- a/docs/Articles.md
+++ b/docs/Articles.md
@@ -16,6 +16,7 @@ See also [case studies](https://docs.victoriametrics.com/CaseStudies.html).
 
 ## Third-party articles and slides about VictoriaMetrics
 
+* [Why Roblox Picked VictoriaMetrics for Observability Data Overhaul](https://www.datanami.com/2023/05/30/why-roblox-picked-victoriametrics-for-observability-data-overhaul/)
 * [The (Almost) Infinitely Scalable Open Source Monitoring Dream](https://www.forbes.com/sites/adrianbridgwater/2022/08/16/the-almost-infinitely-scalable-open-source-monitoring-dream/)
 * [Monitoring at scale with Victoria Metrics](https://tech.bedrockstreaming.com/2022/09/06/monitoring-at-scale-with-victoriametrics.html)
 * [Optimizing Linkerd metrics in Prometheus](https://aatarasoff.medium.com/optimizing-linkerd-metrics-in-prometheus-de607ec10f6b)
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 1e5edc3ea..659250985 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -24,7 +24,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
 
 ## tip
 
-* SECURITY: upgrade Go builder from Go1.20.4 to Go1.20.5. See [the list of issues addressed in Go1.20.5](https://github.com/golang/go/issues?q=milestone%3AGo1.20.5+label%3ACherryPickApproved).
+* SECURITY: upgrade base docker image (alpine) from 3.18.0 to 3.18.2. See [alpine 3.18.2 release notes](https://alpinelinux.org/posts/Alpine-3.15.9-3.16.6-3.17.4-3.18.2-released.html).
 
 * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): Adds `enable_http2` on scrape configuration level. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4283). Thanks to @Haleygo for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4295).
 * FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): add verbose output for docker installations or when TTY isn't available. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4081).
@@ -35,6 +35,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
 * FEATURE: accept timestamps in milliseconds at `start`, `end` and `time` query args in [Prometheus querying API](https://docs.victoriametrics.com/#prometheus-querying-api-usage). See [these docs](https://docs.victoriametrics.com/#timestamp-formats) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4459).
 * FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): update retry policy for pushing data to `-remoteWrite.url`. By default, vmalert will make multiple retry attempts with exponential delay. The total time spent during retry attempts shouldn't exceed `-remoteWrite.retryMaxTime` (default is 30s). When retry time is exceeded vmalert drops the data dedicated for `-remoteWrite.url`. Before, vmalert dropped data after 5 retry attempts with 1s delay between attempts (not configurable). See `-remoteWrite.retryMinInterval` and `-remoteWrite.retryMaxTime` cmd-line flags.
 * FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): expose `vmalert_remotewrite_send_duration_seconds_total` counter, which can be used for determining high saturation of every connection to remote storage with an alerting query `sum(rate(vmalert_remotewrite_send_duration_seconds_total[5m])) by(job, instance) > 0.9 * max(vmalert_remotewrite_concurrency) by(job, instance)`. This query triggers when a connection is saturated by more than 90%. This usually means that `-remoteWrite.concurrency` command-line flag must be increased in order to increase the number of concurrent writings into remote endpoint. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4516).
+* FEATUTE: [vmalert](https://docs.victoriametrics.com/vmalert.html): display the error message received during unsuccessful config reload in vmalert's UI. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4076) for details.
 * FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth.html): expose `vmauth_user_request_duration_seconds` and `vmauth_unauthorized_user_request_duration_seconds` summary metrics for measuring requests latency per user.
 * FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): show backup progress percentage in log during backup uploading. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4460).
 * FEATURE: [vmrestore](https://docs.victoriametrics.com/vmrestore.html): show restoring progress percentage in log during backup downloading. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4460).
@@ -43,14 +44,25 @@ The following tip changes can be tested by building VictoriaMetrics components f
   `--search.maxGraphiteTagKeys` for limiting the number of tag keys returned from Graphite `/tags`, `/tags/autoComplete/*`, `/tags/findSeries` API. 
   `--search.maxGraphiteTagValues` for limiting the number of tag values returned Graphite `/tags/<tag_name>` API. 
   Remove redundant limit from [Prometheus api/v1/series](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#prometheus-querying-api-usage). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4339).
+* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix application routing issues and problems with manual URL changes. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4408).
+* BUGFIX: add validation for invalid [partial RFC3339 timestamp formats](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#timestamp-formats) in query and export APIs.
+* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): interrupt explore procedure in influx mode if vmctl found no numeric fields.
+
+## [v1.91.3](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.91.3)
+
+Released at 2023-06-30
+
+* SECURITY: upgrade Go builder from Go1.20.4 to Go1.20.5. See [the list of issues addressed in Go1.20.5](https://github.com/golang/go/issues?q=milestone%3AGo1.20.5+label%3ACherryPickApproved).
+
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): fix panic on vmagent shutdown which could lead to loosing aggregation results which were not flushed to remote yet. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4407) for details.
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): fixed service name detection for [consulagent service discovery](https://docs.victoriametrics.com/sd_configs.html?highlight=consulagent#consulagent_sd_configs) in case of a difference in service name and service id. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4390) for details.
+* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): retry all errors except 4XX status codes while pushing via remote-write to the remote storage. Previously, errors like broken connection could prevent vmalert from retrying the request.
+* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): properly interrupt retry attempts on vmalert shutdown. Before, vmalert could have waited for all retries to finish for shutdown.
 * BUGFIX: [vmbackupmanager](https://docs.victoriametrics.com/vmbackupmanager.html): fix an issue with `vmbackupmanager` not being able to restore data from a backup stored in GCS. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4420) for details.
 * BUGFIX: [storage](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html): Properly creates `parts.json` after migration from versions below `v1.90.0. It must fix errors on start-up after unclean shutdown. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4336) for details.
 * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix a memory leak issue associated with chart updates. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4455).
-* BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix application routing issues and problems with manual URL changes. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4408).
-* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): retry all errors except 4XX status codes while pushing via remote-write to the remote storage. Previously, errors like broken connection could prevent vmalert from retrying the request.
-* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): properly interrupt retry attempts on vmalert shutdown. Before, vmalert could have waited for all retries to finish for shutdown.
+
+
 
 ## [v1.91.2](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.91.2)
 
diff --git a/docs/CaseStudies.md b/docs/CaseStudies.md
index db7b74558..62e06201a 100644
--- a/docs/CaseStudies.md
+++ b/docs/CaseStudies.md
@@ -32,6 +32,7 @@ where you can chat with VictoriaMetrics users to get additional references, revi
   - [MHI Vestas Offshore Wind](#mhi-vestas-offshore-wind)
   - [Percona](#percona)
   - [Razorpay](#razorpay)
+  - [Roblox](#roblox)
   - [Sensedia](#sensedia)
   - [Smarkets](#smarkets)
   - [Synthesio](#synthesio)
@@ -446,6 +447,41 @@ Percona migrated from Prometheus to VictoriaMetrics in the [Percona Monitoring a
 
 See [the full article](https://engineering.razorpay.com/scaling-to-trillions-of-metric-data-points-f569a5b654f2).
 
+## Roblox
+
+[Roblox](https://roblox.com/) builds the tools and platform that empower people to create their own immersive experiences,
+so that any world they can imagine can be brought to life.
+
+With more than 200 million active monthly users, Roblox is one of the most popular gaming platforms on the Internet.
+The company started with Prometheus and InfluxDB for observability, but as volume continued to build,
+Roblox eventually adopted a time-series database called VictoriaMetrics.
+
+That sudden growth coincided with a substantial rebuild of Roblox’s observability system, which informed internal users about
+everything from the condition of Roblox application servers and storage infrastructure to the number of players and player experience.
+
+The original observability system was largely homegrown, consisting of some open source software and internally developed tools.
+It was based on a decentralized model and leveraged individual Prometheus and InfluxDB instances to store data streaming
+in from the infrastructure and the platform, which internal Roblox users analyzed using Grafana and an internally developed tool called RCity.
+
+From a usability perspective, there was no central repository for data or analysis, and engineers had to jump around to different tools
+to get what they needed. It also hurt Roblox’s flexibility to know how the platform was working in a new region or a new country.
+
+And while the simplicity of storing data in key-value pairs aided visualization, it made doing in-depth analysis a real pain.
+
+Lastly, the homegrown observability system hurt reliability for Roblox.
+
+By all accounts, the move to VictoriaMetrics and Grafana has been a success. With a centralized telemetry database and visualization system,
+Roblox engineers don’t have to hunt around for different tools when problems arise, which was source of delay before.
+The new setup has also helped Roblox deliver 100% availability for three straight quarters, despite moving a massive amount of data.
+
+Numbers:
+
+- 200 storage nodes in VictoriaMetrics cluster
+- Active time series: 5 billion
+- Data ingestion rate: 120 million data points per second
+
+See more details [in this article](https://www.datanami.com/2023/05/30/why-roblox-picked-victoriametrics-for-observability-data-overhaul/).
+
 ## Sensedia
 
 [Sensedia](https://www.sensedia.com) is a leading integration solutions provider with more than 120 enterprise clients across a range of sectors. Its world-class portfolio includes: an API Management Platform, Adaptive Governance, Events Hub, Service Mesh, Cloud Connectors and Strategic Professional Services' teams.
diff --git a/docs/README.md b/docs/README.md
index 29bcdf671..4aec3925f 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -19,14 +19,14 @@ VictoriaMetrics is a fast, cost-effective and scalable monitoring solution and t
 VictoriaMetrics is available in [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases),
 [Docker images](https://hub.docker.com/r/victoriametrics/victoria-metrics/), [Snap packages](https://snapcraft.io/victoriametrics)
 and [source code](https://github.com/VictoriaMetrics/VictoriaMetrics). 
-Just download [the latest version of VictoriaMetrics](https://docs.victoriametrics.com/CHANGELOG.html)
-and follow [these instructions](https://docs.victoriametrics.com/Quick-Start.html).
 
 The cluster version of VictoriaMetrics is available [here](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html).
 
 Learn more about [key concepts](https://docs.victoriametrics.com/keyConcepts.html) of VictoriaMetrics and follow the 
 [quick start guide](https://docs.victoriametrics.com/Quick-Start.html) for a better experience.
 
+There is also user-friendly database for logs - [VictoriaLogs](https://docs.victoriametrics.com/VictoriaLogs/).
+
 If you have questions about VictoriaMetrics, then feel free asking them at [VictoriaMetrics community Slack chat](https://slack.victoriametrics.com/).
 
 [Contact us](mailto:info@victoriametrics.com) if you need enterprise support for VictoriaMetrics. 
@@ -121,6 +121,7 @@ Case studies:
 * [MHI Vestas Offshore Wind](https://docs.victoriametrics.com/CaseStudies.html#mhi-vestas-offshore-wind)
 * [Razorpay](https://docs.victoriametrics.com/CaseStudies.html#razorpay)
 * [Percona](https://docs.victoriametrics.com/CaseStudies.html#percona)
+* [Roblox](https://docs.victoriametrics.com/CaseStudies.html#roblox)
 * [Sensedia](https://docs.victoriametrics.com/CaseStudies.html#sensedia)
 * [Smarkets](https://docs.victoriametrics.com/CaseStudies.html#smarkets)
 * [Synthesio](https://docs.victoriametrics.com/CaseStudies.html#synthesio)
@@ -1581,19 +1582,22 @@ See also [how to work with snapshots](#how-to-work-with-snapshots).
 
 ## Retention
 
-Retention is configured with the `-retentionPeriod` command-line flag, which takes a number followed by a time unit character - `h(ours)`, `d(ays)`, `w(eeks)`, `y(ears)`. If the time unit is not specified, a month is assumed. For instance, `-retentionPeriod=3` means that the data will be stored for 3 months and then deleted. The default retention period is one month. The minimum retention period is 24h or 1d.
+Retention is configured with the `-retentionPeriod` command-line flag, which takes a number followed by a time unit 
+character - `h(ours)`, `d(ays)`, `w(eeks)`, `y(ears)`. If the time unit is not specified, a month is assumed. 
+For instance, `-retentionPeriod=3` means that the data will be stored for 3 months and then deleted. 
+The default retention period is one month. The **minimum retention** period is 24h or 1d.
 
 Data is split in per-month partitions inside `<-storageDataPath>/data/{small,big}` folders.
-Data partitions outside the configured retention are deleted on the first day of the new month.
-Each partition consists of one or more data parts. Data parts outside the configured retention are eventually deleted during
-[background merge](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282).
+**Data partitions** outside the configured retention are deleted **on the first day of the new month**.
+Each partition consists of one or more **data parts**. Data parts outside the configured retention 
+are **eventually deleted** during [background merge](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282).
+The time range covered by data part is **not limited by retention period unit**. One data part can cover hours or days of 
+data. Hence, a data part can be deleted only **when fully outside the configured retention**.
+See more about partitions and parts [here](#storage).
 
 The maximum disk space usage for a given `-retentionPeriod` is going to be (`-retentionPeriod` + 1) months.
 For example, if `-retentionPeriod` is set to 1, data for January is deleted on March 1st.
 
-Please note, the time range covered by data part is not limited by retention period unit. Hence, data part may contain data
-for multiple days and will be deleted only when fully outside the configured retention.
-
 It is safe to extend `-retentionPeriod` on existing data. If `-retentionPeriod` is set to a lower
 value than before, then data outside the configured period will be eventually deleted.
 
@@ -1662,9 +1666,6 @@ Downsampling happens during [background merges](https://docs.victoriametrics.com
 and can't be performed if there is not enough of free disk space or if vmstorage 
 is in [read-only mode](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#readonly-mode).
 
-When setting multiple downsampling periods, it is required for the periods to be multiples of each other. For example,
-`-downsampling.period=30d:1m,60d:30m` is valid, but `-downsampling.period=30d:45s,60d:60s` is invalid.
-
 The downsampling can be evaluated for free by downloading and using enterprise binaries from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
 
 ## Multi-tenancy
@@ -2062,8 +2063,7 @@ It is recommended disabling query cache with `-search.disableCache` command-line
 historical data with timestamps from the past, since the cache assumes that the data is written with
 the current timestamps. Query cache can be enabled after the backfilling is complete.
 
-An alternative solution is to query `/internal/resetRollupResultCache` url after backfilling is complete. This will reset
-the query cache, which could contain incomplete data cached during the backfilling.
+An alternative solution is to query [/internal/resetRollupResultCache](https://docs.victoriametrics.com/url-examples.html#internalresetRollupResultCache) handler after the backfilling is complete. This will reset the query cache, which could contain incomplete data cached during the backfilling.
 
 Yet another solution is to increase `-search.cacheTimestampOffset` flag value in order to disable caching
 for data with timestamps close to the current time. Single-node VictoriaMetrics automatically resets response
diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md
index 715b3fcb2..5a16d55bc 100644
--- a/docs/Single-server-VictoriaMetrics.md
+++ b/docs/Single-server-VictoriaMetrics.md
@@ -27,14 +27,14 @@ VictoriaMetrics is a fast, cost-effective and scalable monitoring solution and t
 VictoriaMetrics is available in [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases),
 [Docker images](https://hub.docker.com/r/victoriametrics/victoria-metrics/), [Snap packages](https://snapcraft.io/victoriametrics)
 and [source code](https://github.com/VictoriaMetrics/VictoriaMetrics). 
-Just download [the latest version of VictoriaMetrics](https://docs.victoriametrics.com/CHANGELOG.html)
-and follow [these instructions](https://docs.victoriametrics.com/Quick-Start.html).
 
 The cluster version of VictoriaMetrics is available [here](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html).
 
 Learn more about [key concepts](https://docs.victoriametrics.com/keyConcepts.html) of VictoriaMetrics and follow the 
 [quick start guide](https://docs.victoriametrics.com/Quick-Start.html) for a better experience.
 
+There is also user-friendly database for logs - [VictoriaLogs](https://docs.victoriametrics.com/VictoriaLogs/).
+
 If you have questions about VictoriaMetrics, then feel free asking them at [VictoriaMetrics community Slack chat](https://slack.victoriametrics.com/).
 
 [Contact us](mailto:info@victoriametrics.com) if you need enterprise support for VictoriaMetrics. 
@@ -129,6 +129,7 @@ Case studies:
 * [MHI Vestas Offshore Wind](https://docs.victoriametrics.com/CaseStudies.html#mhi-vestas-offshore-wind)
 * [Razorpay](https://docs.victoriametrics.com/CaseStudies.html#razorpay)
 * [Percona](https://docs.victoriametrics.com/CaseStudies.html#percona)
+* [Roblox](https://docs.victoriametrics.com/CaseStudies.html#roblox)
 * [Sensedia](https://docs.victoriametrics.com/CaseStudies.html#sensedia)
 * [Smarkets](https://docs.victoriametrics.com/CaseStudies.html#smarkets)
 * [Synthesio](https://docs.victoriametrics.com/CaseStudies.html#synthesio)
@@ -1589,19 +1590,22 @@ See also [how to work with snapshots](#how-to-work-with-snapshots).
 
 ## Retention
 
-Retention is configured with the `-retentionPeriod` command-line flag, which takes a number followed by a time unit character - `h(ours)`, `d(ays)`, `w(eeks)`, `y(ears)`. If the time unit is not specified, a month is assumed. For instance, `-retentionPeriod=3` means that the data will be stored for 3 months and then deleted. The default retention period is one month. The minimum retention period is 24h or 1d.
+Retention is configured with the `-retentionPeriod` command-line flag, which takes a number followed by a time unit 
+character - `h(ours)`, `d(ays)`, `w(eeks)`, `y(ears)`. If the time unit is not specified, a month is assumed. 
+For instance, `-retentionPeriod=3` means that the data will be stored for 3 months and then deleted. 
+The default retention period is one month. The **minimum retention** period is 24h or 1d.
 
 Data is split in per-month partitions inside `<-storageDataPath>/data/{small,big}` folders.
-Data partitions outside the configured retention are deleted on the first day of the new month.
-Each partition consists of one or more data parts. Data parts outside the configured retention are eventually deleted during
-[background merge](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282).
+**Data partitions** outside the configured retention are deleted **on the first day of the new month**.
+Each partition consists of one or more **data parts**. Data parts outside the configured retention 
+are **eventually deleted** during [background merge](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282).
+The time range covered by data part is **not limited by retention period unit**. One data part can cover hours or days of 
+data. Hence, a data part can be deleted only **when fully outside the configured retention**.
+See more about partitions and parts [here](#storage).
 
 The maximum disk space usage for a given `-retentionPeriod` is going to be (`-retentionPeriod` + 1) months.
 For example, if `-retentionPeriod` is set to 1, data for January is deleted on March 1st.
 
-Please note, the time range covered by data part is not limited by retention period unit. Hence, data part may contain data
-for multiple days and will be deleted only when fully outside the configured retention.
-
 It is safe to extend `-retentionPeriod` on existing data. If `-retentionPeriod` is set to a lower
 value than before, then data outside the configured period will be eventually deleted.
 
@@ -1670,9 +1674,6 @@ Downsampling happens during [background merges](https://docs.victoriametrics.com
 and can't be performed if there is not enough of free disk space or if vmstorage 
 is in [read-only mode](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#readonly-mode).
 
-When setting multiple downsampling periods, it is required for the periods to be multiples of each other. For example,
-`-downsampling.period=30d:1m,60d:30m` is valid, but `-downsampling.period=30d:45s,60d:60s` is invalid.
-
 The downsampling can be evaluated for free by downloading and using enterprise binaries from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
 
 ## Multi-tenancy
@@ -2070,8 +2071,7 @@ It is recommended disabling query cache with `-search.disableCache` command-line
 historical data with timestamps from the past, since the cache assumes that the data is written with
 the current timestamps. Query cache can be enabled after the backfilling is complete.
 
-An alternative solution is to query `/internal/resetRollupResultCache` url after backfilling is complete. This will reset
-the query cache, which could contain incomplete data cached during the backfilling.
+An alternative solution is to query [/internal/resetRollupResultCache](https://docs.victoriametrics.com/url-examples.html#internalresetRollupResultCache) handler after the backfilling is complete. This will reset the query cache, which could contain incomplete data cached during the backfilling.
 
 Yet another solution is to increase `-search.cacheTimestampOffset` flag value in order to disable caching
 for data with timestamps close to the current time. Single-node VictoriaMetrics automatically resets response
diff --git a/docs/VictoriaLogs/LogsQL.md b/docs/VictoriaLogs/LogsQL.md
index fc0c67f92..aa2bcdad3 100644
--- a/docs/VictoriaLogs/LogsQL.md
+++ b/docs/VictoriaLogs/LogsQL.md
@@ -371,26 +371,27 @@ See also:
 
 Is you need to search for log messages with the specific phrase inside them, then just wrap the phrase in quotes.
 The phrase can contain any chars, including whitespace, punctuation, parens, etc. They are taken into account during the search.
-For example, the following query matches [log messages](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#message-field) with `cannot open file` phrase inside them:
+For example, the following query matches [log messages](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#message-field)
+with `ssh: login fail` phrase inside them:
 
 ```logsql
-"cannot open file"
+"ssh: login fail"
 ```
 
 This query matches the following [log messages](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#message-field):
 
-- `ERROR: cannot open file /foo/bar/baz`
-- `cannot open file: permission denied`
+- `ERROR: ssh: login fail for user "foobar"`
+- `ssh: login fail!`
 
 This query doesn't match the following log messages:
 
-- `cannot  open  file`, since the number of whitespace chars between words doesn't match the number of whitespace chars in the search phrase.
-  Use `seq("cannot", "open", "file")` query instead. See [these docs](#sequence-filter) for details.
-- `open file: cannot do this`, since the message doesn't contain the full phrase requested in the query. If you need matching a message
-  with all the [words](#word) listed in the query, then use `cannot AND open AND file` query. See [these docs](#logical-filter) for details.
-- `cannot open files`, since the message ends with `files` [word](#word) instead of `file` word. Use `"cannot open file"*` query for this case.
+- `ssh login fail`, since the message misses `:` char just after the `ssh`.
+  Use `seq("ssh", "login", "fail")` query if log messages with the sequence of these words must be found. See [these docs](#sequence-filter) for details.
+- `login fail: ssh error`, since the message doesn't contain the full phrase requested in the query. If you need matching a message
+  with all the [words](#word) listed in the query, then use `ssh AND login AND fail` query. See [these docs](#logical-filter) for details.
+- `ssh: login failed`, since the message ends with `failed` [word](#word) instead of `fail` word. Use `"ssh: login fail"*` query for this case.
   See [these docs](#prefix-filter) for details.
-- `Cannot open file: failure`, since the `Cannot` word starts with capital letter. Use `i("cannot open file")` for this case.
+- `SSH: login fail`, since the `SSH` word is in capital letters. Use `i("ssh: login fail")` for case-insensitive search.
   See [these docs](#case-insensitive-filter) for details.
 
 By default the given phrase is searched in the [`_msg` field](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#message-field).
@@ -755,37 +756,45 @@ See also:
 ### Regexp filter
 
 LogsQL supports regular expression filter with [re2 syntax](https://github.com/google/re2/wiki/Syntax) via `re(...)` expression.
-For example, the following query returns all the log messages containing `error` or `warn` susbstrings:
+For example, the following query returns all the log messages containing `err` or `warn` susbstrings:
 
 ```logsql
-re("error|warn")
+re("err|warn")
 ```
 
-The query matches the following [log messages](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#message-field):
+The query matches the following [log messages](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#message-field), which contain either `err` or `warn` substrings:
 
 - `error: cannot read data`
-- `A warning has been raised`
+- `2 warnings have been raised`
+- `data trasferring finished`
+
+The query doesn't match the following log messages:
+
+- `ERROR: cannot open file`, since the `ERROR` word is in uppercase letters. Use `re("(?i)(err|warn)")` query for case-insensitive regexp search.
+  See [these docs](https://github.com/google/re2/wiki/Syntax) for details. See also [case-insenstive filter docs](#case-insensitive-filter).
+- `it is warmer than usual`, since it doesn't contain neither `err` nor `warn` substrings.
 
 By default the `re()` filter is applied to the [`_msg` field](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#message-field).
 Specify the needed [field name](https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#data-model) in front of the filter
-in order to apply it to the given field. For example, the following query matches `event.original` field containing either `error` or `warn` substrings:
+in order to apply it to the given field. For example, the following query matches `event.original` field containing either `err` or `warn` substrings:
 
 ```logsql
-event.original:re("error|warn")
+event.original:re("err|warn")
 ```
 
 If the field name contains special chars, which may clash with the query syntax, then it may be put into quotes in the query.
-For example, the following query matches `event:original` field containing either `error` or `warn` substrings:
+For example, the following query matches `event:original` field containing either `err` or `warn` substrings:
 
 ```logsql
-"event:original":re("error|warn")
+"event:original":re("err|warn")
 ```
 
 Performance tips:
 
 - Prefer combining simple [word filter](#word-filter) with [logical filter](#logical-filter) instead of using regexp filter.
   For example, the `re("error|warning")` query can be substituted with `error OR warning` query, which usually works much faster.
-  See also [multi-exact filter](#multi-exact-filter).
+  Note that the `re("error|warning")` matches `errors` as well as `warnings` [words](#word), while `error OR warning` matches
+  only the specified [words](#word). See also [multi-exact filter](#multi-exact-filter).
 - Prefer moving the regexp filter to the end of the [logical filter](#logical-filter), so lightweighter filters are executed first.
 - Prefer using `exact_prefix("some prefix")` instead of `re("^some prefix")`, since the [exact_prefix()](#exact-prefix-filter) works much faster than the `re()` filter.
 - See [other performance tips](#performance-tips).
diff --git a/docs/VictoriaLogs/README.md b/docs/VictoriaLogs/README.md
index 230ea70c8..25c0996fc 100644
--- a/docs/VictoriaLogs/README.md
+++ b/docs/VictoriaLogs/README.md
@@ -122,3 +122,127 @@ log management systems and comparing resource usage + query performance between
 
 Please share benchmark results and ideas on how to improve benchmarks / VictoriaLogs
 via [VictoriaMetrics community channels](https://docs.victoriametrics.com/#community-and-contributions).
+
+## List of command-line flags
+
+Pass `-help` to VictoriaLogs in order to see the list of supported command-line flags with their description:
+
+```
+  -cacheExpireDuration duration
+    	Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
+  -enableTCP6
+    	Whether to enable IPv6 for listening and dialing. By default, only IPv4 TCP and UDP is used
+  -envflag.enable
+    	Whether to enable reading flags from environment variables additionally to command line. Command line flag values have priority over values from environment vars. Flags are read only from command line if this flag isn't set. See https://docs.victoriametrics.com/#environment-variables for more details
+  -envflag.prefix string
+    	Prefix for environment variables if -envflag.enable is set
+  -flagsAuthKey string
+    	Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -fs.disableMmap
+    	Whether to use pread() instead of mmap() for reading data files. By default, mmap() is used for 64-bit arches and pread() is used for 32-bit arches, since they cannot read data files bigger than 2^32 bytes in memory. mmap() is usually faster for reading small data chunks than pread()
+  -futureRetention value
+    	Log entries with timestamps bigger than now+futureRetention are rejected during data ingestion; see https://docs.victoriametrics.com/VictoriaLogs/#retention
+    	The following optional suffixes are supported: h (hour), d (day), w (week), y (year). If suffix isn't set, then the duration is counted in months (default 2d)
+  -gogc int
+    	GOGC to use. See https://tip.golang.org/doc/gc-guide (default 100)
+  -http.connTimeout duration
+    	Incoming http connections are closed after the configured timeout. This may help to spread the incoming load among a cluster of services behind a load balancer. Please note that the real timeout may be bigger by up to 10% as a protection against the thundering herd problem (default 2m0s)
+  -http.disableResponseCompression
+    	Disable compression of HTTP responses to save CPU resources. By default, compression is enabled to save network bandwidth
+  -http.idleConnTimeout duration
+    	Timeout for incoming idle http connections (default 1m0s)
+  -http.maxGracefulShutdownDuration duration
+    	The maximum duration for a graceful shutdown of the HTTP server. A highly loaded server may require increased value for a graceful shutdown (default 7s)
+  -http.pathPrefix string
+    	An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, then all the http requests will be handled on '/foo/bar/*' paths. This may be useful for proxied requests. See https://www.robustperception.io/using-external-urls-and-proxies-with-prometheus
+  -http.shutdownDelay duration
+    	Optional delay before http server shutdown. During this delay, the server returns non-OK responses from /health page, so load balancers can route new requests to other servers
+  -httpAuth.password string
+    	Password for HTTP Basic Auth. The authentication is disabled if -httpAuth.username is empty
+  -httpAuth.username string
+    	Username for HTTP Basic Auth. The authentication is disabled if empty. See also -httpAuth.password
+  -httpListenAddr string
+    	TCP address to listen for http connections. See also -httpListenAddr.useProxyProtocol (default ":9428")
+  -httpListenAddr.useProxyProtocol
+    	Whether to use proxy protocol for connections accepted at -httpListenAddr . See https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt . With enabled proxy protocol http server cannot serve regular /metrics endpoint. Use -pushmetrics.url for metrics pushing
+  -inmemoryDataFlushInterval duration
+    	The interval for guaranteed saving of in-memory data to disk. The saved data survives unclean shutdown such as OOM crash, hardware reset, SIGKILL, etc. Bigger intervals may help increasing lifetime of flash storage with limited write cycles (e.g. Raspberry PI). Smaller intervals increase disk IO load. Minimum supported value is 1s (default 5s)
+  -insert.maxLineSizeBytes size
+    	The maximum size of a single line, which can be read by /insert/* handlers
+    	Supports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB (default 262144)
+  -insert.maxQueueDuration duration
+    	The maximum duration to wait in the queue when -maxConcurrentInserts concurrent insert requests are executed (default 1m0s)
+  -internStringCacheExpireDuration duration
+    	The expiry duration for caches for interned strings. See https://en.wikipedia.org/wiki/String_interning . See also -internStringMaxLen and -internStringDisableCache (default 6m0s)
+  -internStringDisableCache
+    	Whether to disable caches for interned strings. This may reduce memory usage at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringCacheExpireDuration and -internStringMaxLen
+  -internStringMaxLen int
+    	The maximum length for strings to intern. Lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
+  -logIngestedRows
+    	Whether to log all the ingested log entries; this can be useful for debugging of data ingestion; see https://docs.victoriametrics.com/VictoriaLogs/data-ingestion/ ; see also -logNewStreams
+  -logNewStreams
+    	Whether to log creation of new streams; this can be useful for debugging of high cardinality issues with log streams; see https://docs.victoriametrics.com/VictoriaLogs/keyConcepts.html#stream-fields ; see also -logIngestedRows
+  -loggerDisableTimestamps
+    	Whether to disable writing timestamps in logs
+  -loggerErrorsPerSecondLimit int
+    	Per-second limit on the number of ERROR messages. If more than the given number of errors are emitted per second, the remaining errors are suppressed. Zero values disable the rate limit
+  -loggerFormat string
+    	Format for logs. Possible values: default, json (default "default")
+  -loggerJSONFields string
+    	Allows renaming fields in JSON formatted logs. Example: "ts:timestamp,msg:message" renames "ts" to "timestamp" and "msg" to "message". Supported fields: ts, level, caller, msg
+  -loggerLevel string
+    	Minimum level of errors to log. Possible values: INFO, WARN, ERROR, FATAL, PANIC (default "INFO")
+  -loggerOutput string
+    	Output for the logs. Supported values: stderr, stdout (default "stderr")
+  -loggerTimezone string
+    	Timezone to use for timestamps in logs. Timezone must be a valid IANA Time Zone. For example: America/New_York, Europe/Berlin, Etc/GMT+3 or Local (default "UTC")
+  -loggerWarnsPerSecondLimit int
+    	Per-second limit on the number of WARN messages. If more than the given number of warns are emitted per second, then the remaining warns are suppressed. Zero values disable the rate limit
+  -maxConcurrentInserts int
+    	The maximum number of concurrent insert requests. Default value should work for most cases, since it minimizes the memory usage. The default value can be increased when clients send data over slow networks. See also -insert.maxQueueDuration (default 12)
+  -memory.allowedBytes size
+    	Allowed size of system memory VictoriaMetrics caches may occupy. This option overrides -memory.allowedPercent if set to a non-zero value. Too low a value may increase the cache miss rate usually resulting in higher CPU and disk IO usage. Too high a value may evict too much data from OS page cache resulting in higher disk IO usage
+    	Supports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB (default 0)
+  -memory.allowedPercent float
+    	Allowed percent of system memory VictoriaMetrics caches may occupy. See also -memory.allowedBytes. Too low a value may increase cache miss rate usually resulting in higher CPU and disk IO usage. Too high a value may evict too much data from OS page cache which will result in higher disk IO usage (default 60)
+  -metricsAuthKey string
+    	Auth key for /metrics endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -pprofAuthKey string
+    	Auth key for /debug/pprof/* endpoints. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -prevCacheRemovalPercent float
+    	Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
+  -pushmetrics.extraLabel array
+    	Optional labels to add to metrics pushed to -pushmetrics.url . For example, -pushmetrics.extraLabel='instance="foo"' adds instance="foo" label to all the metrics pushed to -pushmetrics.url
+    	Supports an array of values separated by comma or specified via multiple flags.
+  -pushmetrics.interval duration
+    	Interval for pushing metrics to -pushmetrics.url (default 10s)
+  -pushmetrics.url array
+    	Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . By default, metrics exposed at /metrics page aren't pushed to any remote storage
+    	Supports an array of values separated by comma or specified via multiple flags.
+  -retentionPeriod value
+    	Log entries with timestamps older than now-retentionPeriod are automatically deleted; log entries with timestamps outside the retention are also rejected during data ingestion; the minimum supported retention is 1d (one day); see https://docs.victoriametrics.com/VictoriaLogs/#retention
+    	The following optional suffixes are supported: h (hour), d (day), w (week), y (year). If suffix isn't set, then the duration is counted in months (default 7d)
+  -search.maxConcurrentRequests int
+    	The maximum number of concurrent search requests. It shouldn't be high, since a single request can saturate all the CPU cores, while many concurrently executed requests may require high amounts of memory. See also -search.maxQueueDuration (default 6)
+  -search.maxQueryDuration duration
+    	The maximum duration for query execution (default 30s)
+  -search.maxQueueDuration duration
+    	The maximum time the search request waits for execution when -search.maxConcurrentRequests limit is reached; see also -search.maxQueryDuration (default 10s)
+  -select.maxSortBufferSize size
+    	Query results from /select/logsql/query are automatically sorted by _time if their summary size doesn't exceed this value; otherwise query results are streamed in the response without sorting; too big value for this flag may result in high memory usage, since the sorting is performed in memory
+    	Supports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB (default 1048576)
+  -storageDataPath string
+    	Path to directory with the VictoriaLogs data; see https://docs.victoriametrics.com/VictoriaLogs/#storage (default "victoria-logs-data")
+  -tls
+    	Whether to enable TLS for incoming HTTP requests at -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set
+  -tlsCertFile string
+    	Path to file with TLS certificate if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated
+  -tlsCipherSuites array
+    	Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants
+    	Supports an array of values separated by comma or specified via multiple flags.
+  -tlsKeyFile string
+    	Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated
+  -tlsMinVersion string
+    	Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. Supported values: TLS10, TLS11, TLS12, TLS13
+  -version
+```
\ No newline at end of file
diff --git a/docs/url-examples.md b/docs/url-examples.md
index c9cac02db..9124aa99f 100644
--- a/docs/url-examples.md
+++ b/docs/url-examples.md
@@ -618,6 +618,29 @@ Additional information:
 * [How to send Influx data to VictoriaMetrics](https://docs.victoriametrics.com/#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf)
 * [URL Format](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#url-format)
 
+## /internal/resetRollupResultCache
+
+**Resets the response cache for previously served queries. It is recommended to invoke after [backfilling](https://docs.victoriametrics.com/#backfilling) procedure.**
+
+Single-node VictoriaMetrics:
+<div class="with-copy" markdown="1">
+
+```console
+curl -Is http://localhost:8428/internal/resetRollupResultCache
+```
+
+</div>
+
+Cluster version of VictoriaMetrics::
+
+<div class="with-copy" markdown="1">
+
+```console
+curl -Is http://<vmselect>:8481/select/internal/resetRollupResultCache
+```
+
+</div>
+
 ## TCP and UDP
 
 ### How to send data from OpenTSDB-compatible agents to VictoriaMetrics
diff --git a/lib/promutils/time.go b/lib/promutils/time.go
index 1f644ef40..5b999c27f 100644
--- a/lib/promutils/time.go
+++ b/lib/promutils/time.go
@@ -17,6 +17,12 @@ func ParseTime(s string) (float64, error) {
 	return ParseTimeAt(s, currentTimestamp)
 }
 
+const (
+	// time.UnixNano can only store maxInt64, which is 2262
+	maxValidYear = 2262
+	minValidYear = 1970
+)
+
 // ParseTimeAt parses time s in different formats, assuming the given currentTimestamp.
 //
 // See https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#timestamp-formats
@@ -67,6 +73,10 @@ func ParseTimeAt(s string, currentTimestamp float64) (float64, error) {
 		if err != nil {
 			return 0, err
 		}
+		y := t.Year()
+		if y > maxValidYear || y < minValidYear {
+			return 0, fmt.Errorf("cannot parse year from %q: year must in range [%d, %d]", s, minValidYear, maxValidYear)
+		}
 		return tzOffset + float64(t.UnixNano())/1e9, nil
 	}
 	if !strings.Contains(sOrig, "-") {


Test patch:
diff --git a/lib/httputils/time_test.go b/lib/httputils/time_test.go
index 8b5701f96..949b3e47d 100644
--- a/lib/httputils/time_test.go
+++ b/lib/httputils/time_test.go
@@ -53,7 +53,7 @@ func TestGetTimeSuccess(t *testing.T) {
 	f("1562529662.324", 1562529662324)
 	f("-9223372036.854", minTimeMsecs)
 	f("-9223372036.855", minTimeMsecs)
-	f("9223372036.855", maxTimeMsecs)
+	f("1223372036.855", 1223372036855)
 }
 
 func TestGetTimeError(t *testing.T) {
diff --git a/lib/logstorage/encoding_test.go b/lib/logstorage/encoding_test.go
index 3050e531b..ee9ce808f 100644
--- a/lib/logstorage/encoding_test.go
+++ b/lib/logstorage/encoding_test.go
@@ -2,11 +2,18 @@ package logstorage
 
 import (
 	"fmt"
+	"math"
 	"reflect"
 	"strings"
 	"testing"
 )
 
+func isAlmostEqual(a, b int) bool {
+	fa := float64(a)
+	fb := float64(b)
+	return math.Abs(fa-fb) <= math.Abs(fa+fb)*0.17
+}
+
 func TestMarshalUnmarshalStringsBlock(t *testing.T) {
 	f := func(logs string, blockLenExpected int) {
 		t.Helper()
@@ -15,7 +22,7 @@ func TestMarshalUnmarshalStringsBlock(t *testing.T) {
 			a = strings.Split(logs, "\n")
 		}
 		data := marshalStringsBlock(nil, a)
-		if len(data) != blockLenExpected {
+		if !isAlmostEqual(len(data), blockLenExpected) {
 			t.Fatalf("unexpected block length; got %d; want %d; block=%q", len(data), blockLenExpected, data)
 		}
 		sbu := getStringsBlockUnmarshaler()
diff --git a/lib/logstorage/inmemory_part_test.go b/lib/logstorage/inmemory_part_test.go
index 85b2c9f78..8bf59eeb5 100644
--- a/lib/logstorage/inmemory_part_test.go
+++ b/lib/logstorage/inmemory_part_test.go
@@ -93,7 +93,7 @@ func TestInmemoryPartMustInitFromRows(t *testing.T) {
 func checkCompressionRate(t *testing.T, ph *partHeader, compressionRateExpected float64) {
 	t.Helper()
 	compressionRate := float64(ph.UncompressedSizeBytes) / float64(ph.CompressedSizeBytes)
-	if math.Abs(compressionRate-compressionRateExpected) > 0.1 {
+	if math.Abs(compressionRate-compressionRateExpected) > math.Abs(compressionRate+compressionRateExpected)*0.05 {
 		t.Fatalf("unexpected compression rate; got %.1f; want %.1f", compressionRate, compressionRateExpected)
 	}
 }
diff --git a/lib/promutils/time_test.go b/lib/promutils/time_test.go
index cb311348d..38934eea4 100644
--- a/lib/promutils/time_test.go
+++ b/lib/promutils/time_test.go
@@ -91,6 +91,7 @@ func TestParseTimeFailure(t *testing.T) {
 	}
 
 	f("")
+	f("2263")
 	f("23-45:50")
 	f("1223-fo:ba")
 	f("1223-12:ba")