Skip to content

Commit 6d4e8db

Browse files
authored
Fix memory leak in blocks storage ingesters (#2586)
* Fix memory leak in blocks storage ingesters Signed-off-by: Marco Pracucci <[email protected]> * Updated CHANGELOG Signed-off-by: Marco Pracucci <[email protected]>
1 parent 94f36c2 commit 6d4e8db

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
* [BUGFIX] QueryFrontend: fixed a situation where span context missed when downstream_url is used. #2539
8787
* [BUGFIX] Querier: Fixed a situation where querier would crash because of an unresponsive frontend instance. #2569
8888
* [BUGFIX] Fixed collection of tracing spans from Thanos components used internally. #2584
89+
* [BUGFIX] Experimental TSDB: fixed memory leak in ingesters. #2586
8990

9091
## 1.0.1 / 2020-04-23
9192

pkg/ingester/client/compat.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,21 @@ func FromLabelAdaptersToLabels(ls []LabelAdapter) labels.Labels {
229229
// get in input labels whose data structure is reused.
230230
func FromLabelAdaptersToLabelsWithCopy(input []LabelAdapter) labels.Labels {
231231
result := make(labels.Labels, len(input))
232-
233232
for i, l := range input {
234233
result[i] = labels.Label{
235-
Name: l.Name,
236-
Value: l.Value,
234+
Name: copyString(l.Name),
235+
Value: copyString(l.Value),
237236
}
238237
}
239-
240238
return result
241239
}
242240

241+
func copyString(in string) string {
242+
out := make([]byte, len(in))
243+
copy(out, in)
244+
return string(out)
245+
}
246+
243247
// FromLabelsToLabelAdapters casts labels.Labels to []LabelAdapter.
244248
// It uses unsafe, but as LabelAdapter == labels.Label this should be safe.
245249
// This allows us to use labels.Labels directly in protos.

pkg/ingester/client/compat_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import (
55
"reflect"
66
"sort"
77
"testing"
8+
"unsafe"
89

910
"github.com/prometheus/common/model"
1011
"github.com/prometheus/prometheus/pkg/labels"
1112
"github.com/prometheus/prometheus/pkg/textparse"
13+
"github.com/stretchr/testify/assert"
1214
"github.com/thanos-io/thanos/pkg/testutil"
1315
)
1416

@@ -113,6 +115,30 @@ func TestMetricMetadataToMetricTypeToMetricType(t *testing.T) {
113115
}
114116
}
115117

118+
func TestFromLabelAdaptersToLabels(t *testing.T) {
119+
input := []LabelAdapter{{Name: "hello", Value: "world"}}
120+
expected := labels.Labels{labels.Label{Name: "hello", Value: "world"}}
121+
actual := FromLabelAdaptersToLabels(input)
122+
123+
assert.Equal(t, expected, actual)
124+
125+
// All strings must NOT be copied.
126+
assert.Equal(t, uintptr(unsafe.Pointer(&input[0].Name)), uintptr(unsafe.Pointer(&actual[0].Name)))
127+
assert.Equal(t, uintptr(unsafe.Pointer(&input[0].Value)), uintptr(unsafe.Pointer(&actual[0].Value)))
128+
}
129+
130+
func TestFromLabelAdaptersToLabelsWithCopy(t *testing.T) {
131+
input := []LabelAdapter{{Name: "hello", Value: "world"}}
132+
expected := labels.Labels{labels.Label{Name: "hello", Value: "world"}}
133+
actual := FromLabelAdaptersToLabelsWithCopy(input)
134+
135+
assert.Equal(t, expected, actual)
136+
137+
// All strings must be copied.
138+
assert.NotEqual(t, uintptr(unsafe.Pointer(&input[0].Name)), uintptr(unsafe.Pointer(&actual[0].Name)))
139+
assert.NotEqual(t, uintptr(unsafe.Pointer(&input[0].Value)), uintptr(unsafe.Pointer(&actual[0].Value)))
140+
}
141+
116142
func TestQueryResponse(t *testing.T) {
117143
want := buildTestMatrix(10, 10, 10)
118144
have := FromQueryResponse(ToQueryResponse(want))

0 commit comments

Comments
 (0)