Skip to content

Commit b3d7d15

Browse files
GiedriusSbwplotka
authored andcommitted
store/cache: fix broken metric and current index cache size handling (#873)
* store/cache: do not forget to increase c.current on adding new items * store/cache: properly adjust c.curSize * store/cache: prevent uint64 overflow by switching operands Adding uint64(len(b)) to c.curSize might potentially overflow uint64 if the numbers are big enough and then we might not remove enough items from the LRU to satisfy the request. On the other hand, switching the operands avoids this problem because we check before if uint64(len(b)) is bigger than c.maxSize so subtracting uint64(len(b)) will *never* overflow because we know that it is less or equal to c.maxSize. * store/cache: revert ensureFits() changes c.curSize is lowered in onEvict. * store/cache: add smoke tests Add smoke tests for the index cache which check if we set curSize properly, and if removal works.
1 parent 55aaf76 commit b3d7d15

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

pkg/store/cache.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (c *indexCache) ensureFits(b []byte) bool {
127127
if uint64(len(b)) > c.maxSize {
128128
return false
129129
}
130-
for c.curSize+uint64(len(b)) > c.maxSize {
130+
for c.curSize > c.maxSize-uint64(len(b)) {
131131
c.lru.RemoveOldest()
132132
}
133133
return true
@@ -151,6 +151,8 @@ func (c *indexCache) setPostings(b ulid.ULID, l labels.Label, v []byte) {
151151
c.lru.Add(cacheItem{b, cacheKeyPostings(l)}, cv)
152152

153153
c.currentSize.WithLabelValues(cacheTypePostings).Add(float64(len(v)))
154+
c.current.WithLabelValues(cacheTypePostings).Inc()
155+
c.curSize += uint64(len(v))
154156
}
155157

156158
func (c *indexCache) postings(b ulid.ULID, l labels.Label) ([]byte, bool) {
@@ -185,6 +187,8 @@ func (c *indexCache) setSeries(b ulid.ULID, id uint64, v []byte) {
185187
c.lru.Add(cacheItem{b, cacheKeySeries(id)}, cv)
186188

187189
c.currentSize.WithLabelValues(cacheTypeSeries).Add(float64(len(v)))
190+
c.current.WithLabelValues(cacheTypeSeries).Inc()
191+
c.curSize += uint64(len(v))
188192
}
189193

190194
func (c *indexCache) series(b ulid.ULID, id uint64) ([]byte, bool) {

pkg/store/cache_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ package store
33

44
import (
55
"testing"
6+
"time"
67

8+
"github.com/fortytw2/leaktest"
79
"github.com/improbable-eng/thanos/pkg/testutil"
10+
"github.com/oklog/ulid"
811
"github.com/prometheus/client_golang/prometheus"
12+
"github.com/prometheus/tsdb/labels"
913
)
1014

1115
// TestIndexCacheEdge tests the index cache edge cases.
@@ -20,3 +24,38 @@ func TestIndexCacheEdge(t *testing.T) {
2024
fits = cache.ensureFits([]byte{42})
2125
testutil.Equals(t, fits, true)
2226
}
27+
28+
// TestIndexCacheSmoke runs the smoke tests for the index cache.
29+
func TestIndexCacheSmoke(t *testing.T) {
30+
defer leaktest.CheckTimeout(t, 10*time.Second)()
31+
32+
metrics := prometheus.NewRegistry()
33+
cache, err := newIndexCache(metrics, 20)
34+
testutil.Ok(t, err)
35+
36+
blid := ulid.ULID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})
37+
labels := labels.Label{Name: "test", Value: "123"}
38+
39+
cache.setPostings(blid, labels, []byte{42})
40+
41+
p, ok := cache.postings(blid, labels)
42+
testutil.Equals(t, ok, true)
43+
testutil.Equals(t, p, []byte{42})
44+
testutil.Equals(t, cache.curSize, uint64(1))
45+
46+
cache.setSeries(blid, 1234, []byte{42, 42})
47+
48+
s, ok := cache.series(blid, 1234)
49+
testutil.Equals(t, ok, true)
50+
testutil.Equals(t, s, []byte{42, 42})
51+
testutil.Equals(t, cache.curSize, uint64(3))
52+
53+
cache.lru.RemoveOldest()
54+
testutil.Equals(t, cache.curSize, uint64(2))
55+
56+
cache.lru.RemoveOldest()
57+
testutil.Equals(t, cache.curSize, uint64(0))
58+
59+
cache.lru.RemoveOldest()
60+
testutil.Equals(t, cache.curSize, uint64(0))
61+
}

0 commit comments

Comments
 (0)