From 3675a5e56c86ef09f8bb35d93a05012c381b1445 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Thu, 26 Feb 2026 16:41:34 +0100 Subject: [PATCH] tsdb: fix unit mismatch in retention duration on config reload conf.StorageConfig.TSDBConfig.Retention.Time is model.Duration which is type-aliased to time.Duration (nanoseconds), but RetentionDuration is int64 in milliseconds. The missing division by time.Millisecond caused the metric prometheus_tsdb_retention_limit_seconds to be reported 1e6 times too large after a config reload. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- tsdb/db.go | 2 +- tsdb/db_test.go | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tsdb/db.go b/tsdb/db.go index ff1d6876d6..0e92c2b70e 100644 --- a/tsdb/db.go +++ b/tsdb/db.go @@ -1277,7 +1277,7 @@ func (db *DB) ApplyConfig(conf *config.Config) error { // Update retention configuration if provided. if conf.StorageConfig.TSDBConfig.Retention != nil { db.retentionMtx.Lock() - db.opts.RetentionDuration = int64(conf.StorageConfig.TSDBConfig.Retention.Time) + db.opts.RetentionDuration = int64(time.Duration(conf.StorageConfig.TSDBConfig.Retention.Time) / time.Millisecond) db.metrics.retentionDuration.Set((time.Duration(db.opts.RetentionDuration) * time.Millisecond).Seconds()) db.opts.MaxBytes = int64(conf.StorageConfig.TSDBConfig.Retention.Size) db.metrics.maxBytes.Set(float64(db.opts.MaxBytes)) diff --git a/tsdb/db_test.go b/tsdb/db_test.go index bd868d945a..be914cd87d 100644 --- a/tsdb/db_test.go +++ b/tsdb/db_test.go @@ -1743,7 +1743,7 @@ func TestRuntimeRetentionConfigChange(t *testing.T) { StorageConfig: config.StorageConfig{ TSDBConfig: &config.TSDBConfig{ Retention: &config.TSDBRetentionConfig{ - Time: model.Duration(shorterRetentionDuration), + Time: model.Duration(time.Duration(shorterRetentionDuration) * time.Millisecond), }, }, }, @@ -1772,6 +1772,31 @@ func TestRuntimeRetentionConfigChange(t *testing.T) { require.Positive(t, int(prom_testutil.ToFloat64(db.metrics.timeRetentionCount)), "time retention count should be incremented") } +// TestApplyConfigRetentionDurationMetricUnit verifies that after a config +// reload the prometheus_tsdb_retention_limit_seconds metric reports the +// retention in seconds. +func TestApplyConfigRetentionDurationMetricUnit(t *testing.T) { + oneHourMs := int64(time.Hour / time.Millisecond) + db := newTestDB(t, withOpts(&Options{RetentionDuration: oneHourMs})) + + cfg := &config.Config{ + StorageConfig: config.StorageConfig{ + TSDBConfig: &config.TSDBConfig{ + Retention: &config.TSDBRetentionConfig{ + Time: model.Duration(time.Hour), + }, + }, + }, + } + require.NoError(t, db.ApplyConfig(cfg)) + + require.Equal(t, oneHourMs, db.getRetentionDuration()) + + gotSeconds := prom_testutil.ToFloat64(db.metrics.retentionDuration) + wantSeconds := time.Hour.Seconds() + require.Equal(t, wantSeconds, gotSeconds) +} + func TestNotMatcherSelectsLabelsUnsetSeries(t *testing.T) { db := newTestDB(t)