diff --git a/tsdb/head_read.go b/tsdb/head_read.go index 29adc3ee74..2a25e77725 100644 --- a/tsdb/head_read.go +++ b/tsdb/head_read.go @@ -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)) diff --git a/tsdb/ooo_head_read.go b/tsdb/ooo_head_read.go index 26cd4d057e..78ed1c4cdc 100644 --- a/tsdb/ooo_head_read.go +++ b/tsdb/ooo_head_read.go @@ -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)