diff --git a/storage/metric/memory.go b/storage/metric/memory.go index 252d1ac60..00feb4f3f 100644 --- a/storage/metric/memory.go +++ b/storage/metric/memory.go @@ -14,11 +14,12 @@ package metric import ( - "github.com/prometheus/prometheus/model" - "github.com/prometheus/prometheus/utility" "sort" "sync" "time" + + "github.com/prometheus/prometheus/model" + "github.com/prometheus/prometheus/utility" ) // Assuming sample rate of 1 / 15Hz, this allows for one hour's worth of @@ -370,6 +371,15 @@ func (s *memorySeriesStorage) GetMetricForFingerprint(f *model.Fingerprint) (mod return metric, nil } +func (s *memorySeriesStorage) HasFingerprint(f *model.Fingerprint) bool { + s.RLock() + defer s.RUnlock() + + _, has := s.fingerprintToSeries[*f] + + return has +} + func (s *memorySeriesStorage) CloneSamples(f *model.Fingerprint) model.Values { s.RLock() defer s.RUnlock() diff --git a/storage/metric/tiered.go b/storage/metric/tiered.go index aba2511b8..ccbf8b13f 100644 --- a/storage/metric/tiered.go +++ b/storage/metric/tiered.go @@ -309,20 +309,35 @@ func (t *TieredStorage) seriesTooOld(f *model.Fingerprint, i time.Time) (bool, e // BUG(julius): Make this configurable by query layer. i = i.Add(-stalenessLimit) - wm, ok := t.wmCache.Get(f) - if !ok { + wm, cacheHit := t.wmCache.Get(f) + if !cacheHit { value := &dto.MetricHighWatermark{} - present, err := t.DiskStorage.MetricHighWatermarks.Get(f.ToDTO(), value) + diskHit, err := t.DiskStorage.MetricHighWatermarks.Get(f.ToDTO(), value) if err != nil { return false, err } - if present { + + if diskHit { wmTime := time.Unix(*value.Timestamp, 0).UTC() t.wmCache.Set(f, &Watermarks{High: wmTime}) return wmTime.Before(i), nil } - return true, nil + + if !t.memoryArena.HasFingerprint(f) { + return true, nil + } + + samples := t.memoryArena.CloneSamples(f) + if len(samples) == 0 { + return true, nil + } + + newest := samples[0].Timestamp + t.wmCache.Set(f, &Watermarks{High: newest}) + + return false, nil } + return wm.High.Before(i), nil }