fix(tsdb): Clear reset hint when switching between ino and ooo head

Clear the native histogram counter reset hint when switching between the
in-order and out-of-order head.

Given the samples written in this order:
t=1, v=40
t=4, v=30  (reset in in-order)
t=2, v=40
t=3, v=10  (reset in out-of-order)

When we read them back, this is the order:
t=1, v=40
t=2, v=40
t=3, v=10  (reset in readback)
t=4, v=30

Without this fix we also see a reset for t=4, v=30 because the chunk is a
non-overlapping in-order chunk and it is used as is.
The fix is to detect when we switch between in-order and out-of-order
chunks and wrap the next chunk in an iterator that clears the
counter reset as if it overlapped with another chunk.

Signed-off-by: György Krajcsovits <gyorgy.krajcsovits@grafana.com>
This commit is contained in:
György Krajcsovits 2024-10-25 16:53:54 +02:00
parent 38edf62d31
commit 299e08aed8
2 changed files with 12 additions and 3 deletions

View file

@ -262,6 +262,10 @@ func unpackHeadChunkRef(ref chunks.ChunkRef) (seriesID chunks.HeadSeriesRef, chu
return sid, (cid & (oooChunkIDMask - 1)), (cid & oooChunkIDMask) != 0
}
func isOOOChunkID(cid chunks.HeadChunkID) bool {
return (cid & oooChunkIDMask) != 0
}
// LabelValueFor returns label value for the given label name in the series referred to by ID.
func (h *headIndexReader) LabelValueFor(_ context.Context, id storage.SeriesRef, label string) (string, error) {
memSeries := h.head.series.getByID(chunks.HeadSeriesRef(id))

View file

@ -146,9 +146,13 @@ func getOOOSeriesChunks(s *memSeries, mint, maxt int64, lastGarbageCollectedMmap
// In the example 5 overlaps with 7 and 6 overlaps with 8 so we will return
// [5,7], [6,8].
toBeMerged := tmpChks[0]
for _, c := range tmpChks[1:] {
if c.MinTime > toBeMerged.MaxTime {
// This chunk doesn't overlap. Send current toBeMerged to output and start a new one.
prevIsOOO := false
for i, c := range tmpChks[1:] {
currIsOOO := isOOOChunkID(chunks.HeadChunkID(c.Ref))
if c.MinTime > toBeMerged.MaxTime && (i == 0 || prevIsOOO == currIsOOO) {
// This chunk doesn't overlap and we are not switching between in-order
// and out-of-order chunks. Send current toBeMerged to output and start
// a new one.
*chks = append(*chks, toBeMerged)
toBeMerged = c
} else {
@ -162,6 +166,7 @@ func getOOOSeriesChunks(s *memSeries, mint, maxt int64, lastGarbageCollectedMmap
toBeMerged.MaxTime = c.MaxTime
}
}
prevIsOOO = currIsOOO
}
*chks = append(*chks, toBeMerged)