From c7a62b95cea098b677a958bf4e20084bc427aad5 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 24 Mar 2021 15:24:58 +0000 Subject: [PATCH] GetRef() now returns the label set (#8641) The purpose of GetRef() is to allow Append() to be called without the caller needing to copy the labels. To avoid a race where a series is removed from TSDB between the calls to GetRef() and Append(), we return TSDB's copy of the labels. Signed-off-by: Bryan Boreham --- storage/interface.go | 5 +++-- tsdb/db.go | 4 ++-- tsdb/head.go | 11 ++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/storage/interface.go b/storage/interface.go index eb2b5975f..41f6c6497 100644 --- a/storage/interface.go +++ b/storage/interface.go @@ -183,9 +183,10 @@ type Appender interface { // GetRef is an extra interface on Appenders used by downstream projects // (e.g. Cortex) to avoid maintaining a parallel set of references. type GetRef interface { - // Returns reference number that can be used to pass to Appender.Append(). + // Returns reference number that can be used to pass to Appender.Append(), + // and a set of labels that will not cause another copy when passed to Appender.Append(). // 0 means the appender does not have a reference to this series. - GetRef(lset labels.Labels) uint64 + GetRef(lset labels.Labels) (uint64, labels.Labels) } // ExemplarAppender provides an interface for adding samples to exemplar storage, which diff --git a/tsdb/db.go b/tsdb/db.go index b8b3c9970..d4fdc532d 100644 --- a/tsdb/db.go +++ b/tsdb/db.go @@ -797,11 +797,11 @@ type dbAppender struct { var _ storage.GetRef = dbAppender{} -func (a dbAppender) GetRef(lset labels.Labels) uint64 { +func (a dbAppender) GetRef(lset labels.Labels) (uint64, labels.Labels) { if g, ok := a.Appender.(storage.GetRef); ok { return g.GetRef(lset) } - return 0 + return 0, nil } func (a dbAppender) Commit() error { diff --git a/tsdb/head.go b/tsdb/head.go index 4f4e8d51d..353797b60 100644 --- a/tsdb/head.go +++ b/tsdb/head.go @@ -1109,11 +1109,11 @@ func (a *initAppender) AppendExemplar(ref uint64, l labels.Labels, e exemplar.Ex var _ storage.GetRef = &initAppender{} -func (a *initAppender) GetRef(lset labels.Labels) uint64 { +func (a *initAppender) GetRef(lset labels.Labels) (uint64, labels.Labels) { if g, ok := a.app.(storage.GetRef); ok { return g.GetRef(lset) } - return 0 + return 0, nil } func (a *initAppender) Commit() error { @@ -1342,12 +1342,13 @@ func (a *headAppender) AppendExemplar(ref uint64, _ labels.Labels, e exemplar.Ex var _ storage.GetRef = &headAppender{} -func (a *headAppender) GetRef(lset labels.Labels) uint64 { +func (a *headAppender) GetRef(lset labels.Labels) (uint64, labels.Labels) { s := a.head.series.getByHash(lset.Hash(), lset) if s == nil { - return 0 + return 0, nil } - return s.ref + // returned labels must be suitable to pass to Append() + return s.ref, s.lset } func (a *headAppender) log() error {