diff --git a/compact.go b/compact.go index 3860509d8..dc803ef8f 100644 --- a/compact.go +++ b/compact.go @@ -98,11 +98,13 @@ func newCompactorMetrics(r prometheus.Registerer) *compactorMetrics { return m } +// LeveledCompactorOptions are the options for a LeveledCompactor. type LeveledCompactorOptions struct { blockRanges []int64 chunkPool chunks.Pool } +// NewLeveledCompactor returns a LeveledCompactor. func NewLeveledCompactor(r prometheus.Registerer, l log.Logger, opts *LeveledCompactorOptions) *LeveledCompactor { if opts == nil { opts = &LeveledCompactorOptions{ @@ -151,6 +153,10 @@ func (c *LeveledCompactor) Plan(dir string) ([]string, error) { return dms[i].meta.MinTime < dms[j].meta.MinTime }) + return c.plan(dms) +} + +func (c *LeveledCompactor) plan(dms []dirMeta) ([]string, error) { if len(dms) <= 1 { return nil, nil } @@ -170,7 +176,7 @@ func (c *LeveledCompactor) Plan(dir string) ([]string, error) { break } - if meta.Stats.NumSeries/meta.Stats.NumTombstones <= 20 { // 5% + if meta.Stats.NumSeries/(meta.Stats.NumTombstones+1) <= 20 { // 5% return []string{dms[i].dir}, nil } } diff --git a/compact_test.go b/compact_test.go index d9791a080..81cd23b49 100644 --- a/compact_test.go +++ b/compact_test.go @@ -309,3 +309,28 @@ func TestSplitByRange(t *testing.T) { require.Equal(t, exp, splitByRange(blocks, c.trange)) } } + +// See https://github.com/prometheus/prometheus/issues/3064 +func TestNoPanicFor0Tombstones(t *testing.T) { + metas := []dirMeta{ + { + dir: "1", + meta: &BlockMeta{ + MinTime: 0, + MaxTime: 100, + }, + }, + { + dir: "2", + meta: &BlockMeta{ + MinTime: 101, + MaxTime: 200, + }, + }, + } + + c := NewLeveledCompactor(nil, nil, &LeveledCompactorOptions{ + blockRanges: []int64{50}, + }) + c.plan(metas) +}