diff --git a/tsdb/db.go b/tsdb/db.go index 160571a5f9..c2731bb40f 100644 --- a/tsdb/db.go +++ b/tsdb/db.go @@ -980,7 +980,10 @@ func (db *DB) ApplyConfig(conf *config.Config) error { // Create WBL if it was not present and if OOO is enabled with WAL enabled. var wblog *wal.WAL var err error - if !db.oooWasEnabled.Load() && oooTimeWindow > 0 && db.opts.WALSegmentSize >= 0 { + if db.head.wbl != nil { + // The existing WBL from the disk might have been replayed while OOO was disabled. + wblog = db.head.wbl + } else if !db.oooWasEnabled.Load() && oooTimeWindow > 0 && db.opts.WALSegmentSize >= 0 { segmentSize := wal.DefaultSegmentSize // Wal is set to a custom size. if db.opts.WALSegmentSize > 0 { diff --git a/tsdb/db_test.go b/tsdb/db_test.go index 4b01a35341..50b4a0e1e8 100644 --- a/tsdb/db_test.go +++ b/tsdb/db_test.go @@ -5352,3 +5352,52 @@ func TestWblReplayAfterOOODisableAndRestart(t *testing.T) { // We can still query OOO samples when OOO is disabled. verifySamples(allSamples) } + +func TestPanicOnApplyConfig(t *testing.T) { + dir := t.TempDir() + + opts := DefaultOptions() + opts.OutOfOrderTimeWindow = 60 * time.Minute.Milliseconds() + opts.AllowOverlappingQueries = true + + db, err := Open(dir, nil, nil, opts, nil) + require.NoError(t, err) + db.DisableCompactions() + t.Cleanup(func() { + require.NoError(t, db.Close()) + }) + + series1 := labels.FromStrings("foo", "bar1") + var allSamples []tsdbutil.Sample + addSamples := func(fromMins, toMins int64) { + app := db.Appender(context.Background()) + for min := fromMins; min <= toMins; min++ { + ts := min * time.Minute.Milliseconds() + _, err := app.Append(0, series1, ts, float64(ts)) + require.NoError(t, err) + allSamples = append(allSamples, sample{t: ts, v: float64(ts)}) + } + require.NoError(t, app.Commit()) + } + + // In-order samples. + addSamples(290, 300) + // OOO samples. + addSamples(250, 260) + + // Restart DB with OOO disabled. + require.NoError(t, db.Close()) + opts.OutOfOrderTimeWindow = 0 + db, err = Open(db.dir, nil, prometheus.NewRegistry(), opts, nil) + require.NoError(t, err) + + // ApplyConfig with OOO enabled and expect no panic. + err = db.ApplyConfig(&config.Config{ + StorageConfig: config.StorageConfig{ + TSDBConfig: &config.TSDBConfig{ + OutOfOrderTimeWindow: 60 * time.Minute.Milliseconds(), + }, + }, + }) + require.NoError(t, err) +}