From 588985f0d32aeb8965e53d533d735432d87f5c2e Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Wed, 6 May 2026 15:53:42 +0700 Subject: [PATCH 1/4] lib/logstorage: fix uniq_values merge in cluster queries --- docs/victorialogs/CHANGELOG.md | 1 + lib/logstorage/stats_uniq_values.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docs/victorialogs/CHANGELOG.md b/docs/victorialogs/CHANGELOG.md index fbce3f0e7c..b8b4a5d54d 100644 --- a/docs/victorialogs/CHANGELOG.md +++ b/docs/victorialogs/CHANGELOG.md @@ -26,6 +26,7 @@ according to the following docs: * FEATURE: [alerts](https://github.com/VictoriaMetrics/VictoriaLogs/blob/master/deployment/docker/rules): add new alerting rules `PersistentQueueRunsOutOfSpaceIn12Hours` and `PersistentQueueRunsOutOfSpaceIn4Hours` for `vlagent` persistent queue capacity. These alerts help users to take proactive actions before `vlagent` starts dropping logs due to insufficient persistent queue space. See [#10193](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10193) * FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): remove the `Date format` setting and always display timestamps with nanosecond precision. See [#1161](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1161). +* BUGFIX: [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/): fix panic when using [`uniq_values()`](https://docs.victoriametrics.com/victorialogs/logsql/#uniq_values-stats) in the [`stats` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe) in VictoriaLogs cluster if the same group contains empty partial values on one `vlstorage` node and non-empty partial values on another `vlstorage` node. See [#1383](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1383). * BUGFIX: [vlagent](https://docs.victoriametrics.com/victorialogs/vlagent/): hide sensitive values passed via `-remoteWrite.proxyURL` in `/metrics`, `/flags`, and startup logs. Previously these values could be exposed in plain text. See [#1320](https://github.com/VictoriaMetrics/VictoriaLogs/pull/1320). * BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): sanitize markdown URLs in logs rendered with `markdown parsing` enabled, allowing only `http`, `https`, `mailto`, and `tel` schemes for active links and images. See [#1313](https://github.com/VictoriaMetrics/VictoriaLogs/pull/1313). * BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): improve context view highlight visibility in dark theme. The selected log entry is now highlighted with a more visible blue tint instead of barely visible gray background. See [#1196](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1196). diff --git a/lib/logstorage/stats_uniq_values.go b/lib/logstorage/stats_uniq_values.go index 0a7493373e..39258cbe8d 100644 --- a/lib/logstorage/stats_uniq_values.go +++ b/lib/logstorage/stats_uniq_values.go @@ -144,12 +144,18 @@ func (sup *statsUniqValuesProcessor) mergeState(_ *chunkedAllocator, sf statsFun } src := sfp.(*statsUniqValuesProcessor) + if len(src.m) == 0 { + return + } if len(src.m) > 100_000 { // Postpone merging too big number of items in parallel sup.ms = append(sup.ms, src.m) return } + if sup.m == nil { + sup.m = make(map[string]struct{}, len(src.m)) + } for k := range src.m { if _, ok := sup.m[k]; !ok { sup.m[k] = struct{}{} From 6202bb5b453b50c1a638e26c5b6121b6402b03b0 Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Wed, 6 May 2026 16:03:09 +0700 Subject: [PATCH 2/4] docs: make uniq_values cluster bug fix easier to understand --- docs/victorialogs/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/victorialogs/CHANGELOG.md b/docs/victorialogs/CHANGELOG.md index b8b4a5d54d..33d945eabd 100644 --- a/docs/victorialogs/CHANGELOG.md +++ b/docs/victorialogs/CHANGELOG.md @@ -26,7 +26,7 @@ according to the following docs: * FEATURE: [alerts](https://github.com/VictoriaMetrics/VictoriaLogs/blob/master/deployment/docker/rules): add new alerting rules `PersistentQueueRunsOutOfSpaceIn12Hours` and `PersistentQueueRunsOutOfSpaceIn4Hours` for `vlagent` persistent queue capacity. These alerts help users to take proactive actions before `vlagent` starts dropping logs due to insufficient persistent queue space. See [#10193](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10193) * FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): remove the `Date format` setting and always display timestamps with nanosecond precision. See [#1161](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1161). -* BUGFIX: [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/): fix panic when using [`uniq_values()`](https://docs.victoriametrics.com/victorialogs/logsql/#uniq_values-stats) in the [`stats` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe) in VictoriaLogs cluster if the same group contains empty partial values on one `vlstorage` node and non-empty partial values on another `vlstorage` node. See [#1383](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1383). +* BUGFIX: [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/): fix panic when using [`uniq_values()`](https://docs.victoriametrics.com/victorialogs/logsql/#uniq_values-stats) in the [`stats` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe) in VictoriaLogs cluster when some `vlstorage` nodes return no values for the requested field while other `vlstorage` nodes return values for the same group. See [#1383](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1383). * BUGFIX: [vlagent](https://docs.victoriametrics.com/victorialogs/vlagent/): hide sensitive values passed via `-remoteWrite.proxyURL` in `/metrics`, `/flags`, and startup logs. Previously these values could be exposed in plain text. See [#1320](https://github.com/VictoriaMetrics/VictoriaLogs/pull/1320). * BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): sanitize markdown URLs in logs rendered with `markdown parsing` enabled, allowing only `http`, `https`, `mailto`, and `tel` schemes for active links and images. See [#1313](https://github.com/VictoriaMetrics/VictoriaLogs/pull/1313). * BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): improve context view highlight visibility in dark theme. The selected log entry is now highlighted with a more visible blue tint instead of barely visible gray background. See [#1196](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1196). From 5476033ab13181936f4defc43cbb0b4759715020 Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Fri, 15 May 2026 10:59:28 +0700 Subject: [PATCH 3/4] lib/logstorage: simplify uniq_values merge path --- lib/logstorage/stats_uniq_values.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/logstorage/stats_uniq_values.go b/lib/logstorage/stats_uniq_values.go index 39258cbe8d..48f4010588 100644 --- a/lib/logstorage/stats_uniq_values.go +++ b/lib/logstorage/stats_uniq_values.go @@ -144,9 +144,6 @@ func (sup *statsUniqValuesProcessor) mergeState(_ *chunkedAllocator, sf statsFun } src := sfp.(*statsUniqValuesProcessor) - if len(src.m) == 0 { - return - } if len(src.m) > 100_000 { // Postpone merging too big number of items in parallel sup.ms = append(sup.ms, src.m) From c9e2009e0c2c325dda5f717ba71a6025db0bc613 Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Sat, 16 May 2026 14:55:49 +0700 Subject: [PATCH 4/4] apptest: add test for uniq_values merge in cluster queries --- apptest/tests/vlcluster_test.go | 28 ++++++++++++++++++++++++++++ apptest/vlcluster.go | 5 +++++ 2 files changed, 33 insertions(+) diff --git a/apptest/tests/vlcluster_test.go b/apptest/tests/vlcluster_test.go index c312c2501b..02891428c8 100644 --- a/apptest/tests/vlcluster_test.go +++ b/apptest/tests/vlcluster_test.go @@ -8,6 +8,34 @@ import ( "github.com/VictoriaMetrics/VictoriaLogs/apptest" ) +// TestVlclusterUniqValuesMerge verifies that uniq_values correctly merges results when some storage nodes have no matching values. +func TestVlclusterUniqValuesMerge(t *testing.T) { + fs.MustRemoveDir(t.Name()) + tc := apptest.NewTestCase(t) + defer tc.Stop() + sut := tc.MustStartDefaultVlcluster() + + // Write the same group to two storage nodes. The first node has no x values, + // while the second node has x values. This exercises merging a non-empty + // uniq_values state into an empty destination state at vlselect. + storage0 := sut.StorageNode(0) + storage0.JSONLineWrite(t, []string{ + `{"_msg":"no x","host":"h1","_time":"2025-01-01T01:00:00Z"}`, + }, apptest.IngestOpts{}) + storage0.ForceFlush(t) + + storage1 := sut.StorageNode(1) + storage1.JSONLineWrite(t, []string{ + `{"_msg":"has x","host":"h1","x":"a","_time":"2025-01-01T01:00:00Z"}`, + }, apptest.IngestOpts{}) + storage1.ForceFlush(t) + + got := sut.LogsQLQuery(t, `* | stats by (host) uniq_values(x) as values`, apptest.QueryOpts{}) + assertLogsQLResponseEqual(t, got, &apptest.LogsQLQueryResponse{ + LogLines: []string{`{"host":"h1","values":"[\"a\"]"}`}, + }) +} + // TestVlclusterIngestAndQuery verifies that logs are correctly ingested and queried from cluster. func TestVlclusterIngestAndQuery(t *testing.T) { fs.MustRemoveDir(t.Name()) diff --git a/apptest/vlcluster.go b/apptest/vlcluster.go index f9214bee9e..df4880a62b 100644 --- a/apptest/vlcluster.go +++ b/apptest/vlcluster.go @@ -225,6 +225,11 @@ func (app *Vlcluster) LogsQLQueryRaw(t *testing.T, query string, opts QueryOpts) return app.selectNode.cli.PostForm(t, url, values) } +// StorageNode returns the i-th storage node, allowing direct log ingestion that bypasses the insert node. +func (app *Vlcluster) StorageNode(i int) *Vlsingle { + return app.storageNodes[i] +} + // String returns the string representation of the app state. func (app *Vlcluster) String() string { return "Vlcluster"