From ac242663f577798f3eeb106fd423c2460e244b6c Mon Sep 17 00:00:00 2001 From: Ben Ye Date: Mon, 23 Nov 2020 06:01:52 -0500 Subject: [PATCH 1/7] Fix query frontend regression on release v0.17.0 (#3480) * query-frontend: make POST-request to downstream url for labels and series api endpoints (#3444) Signed-off-by: Alexander Tunik <2braven@gmail.com> * remove default response cache config Signed-off-by: Ben Ye * ensure order when merging multiple responses Signed-off-by: Ben Ye Co-authored-by: Alexander Tunik <2braven@gmail.com> --- cmd/thanos/query_frontend.go | 6 +- pkg/queryfrontend/labels_codec.go | 16 +-- pkg/queryfrontend/labels_codec_test.go | 157 ++++++++++++++++++++++++- pkg/store/labelpb/label.go | 24 ++++ pkg/store/labelpb/label_test.go | 89 ++++++++++++++ test/e2e/query_frontend_test.go | 27 ++++- test/e2e/query_test.go | 14 +-- 7 files changed, 306 insertions(+), 27 deletions(-) diff --git a/cmd/thanos/query_frontend.go b/cmd/thanos/query_frontend.go index afd0a9d294..fd97747331 100644 --- a/cmd/thanos/query_frontend.go +++ b/cmd/thanos/query_frontend.go @@ -51,12 +51,10 @@ func registerQueryFrontend(app *extkingpin.App) { MaxBodySize: 10 * 1024 * 1024, }, QueryRangeConfig: queryfrontend.QueryRangeConfig{ - Limits: &cortexvalidation.Limits{}, - ResultsCacheConfig: &queryrange.ResultsCacheConfig{}, + Limits: &cortexvalidation.Limits{}, }, LabelsConfig: queryfrontend.LabelsConfig{ - Limits: &cortexvalidation.Limits{}, - ResultsCacheConfig: &queryrange.ResultsCacheConfig{}, + Limits: &cortexvalidation.Limits{}, }, }, } diff --git a/pkg/queryfrontend/labels_codec.go b/pkg/queryfrontend/labels_codec.go index 4d922751fa..246a8592bc 100644 --- a/pkg/queryfrontend/labels_codec.go +++ b/pkg/queryfrontend/labels_codec.go @@ -49,20 +49,21 @@ func NewThanosLabelsCodec(partialResponse bool, defaultMetadataTimeRange time.Du } } +// MergeResponse merges multiple responses into a single Response. It needs to dedup the responses and ensure the order. func (c labelsCodec) MergeResponse(responses ...queryrange.Response) (queryrange.Response, error) { if len(responses) == 0 { + // Empty response for label_names, label_values and series API. return &ThanosLabelsResponse{ Status: queryrange.StatusSuccess, Data: []string{}, }, nil } - if len(responses) == 1 { - return responses[0], nil - } - switch responses[0].(type) { case *ThanosLabelsResponse: + if len(responses) == 1 { + return responses[0], nil + } set := make(map[string]struct{}) for _, res := range responses { @@ -85,23 +86,18 @@ func (c labelsCodec) MergeResponse(responses ...queryrange.Response) (queryrange case *ThanosSeriesResponse: seriesData := make([]labelpb.ZLabelSet, 0) - // seriesString is used in soring so we don't have to calculate the string of label sets again. - seriesString := make([]string, 0) uniqueSeries := make(map[string]struct{}) for _, res := range responses { for _, series := range res.(*ThanosSeriesResponse).Data { s := series.PromLabels().String() if _, ok := uniqueSeries[s]; !ok { seriesData = append(seriesData, series) - seriesString = append(seriesString, s) uniqueSeries[s] = struct{}{} } } } - sort.Slice(seriesData, func(i, j int) bool { - return seriesString[i] < seriesString[j] - }) + sort.Sort(seriesData) return &ThanosSeriesResponse{ Status: queryrange.StatusSuccess, Data: seriesData, diff --git a/pkg/queryfrontend/labels_codec_test.go b/pkg/queryfrontend/labels_codec_test.go index 5897a86536..a0e6980716 100644 --- a/pkg/queryfrontend/labels_codec_test.go +++ b/pkg/queryfrontend/labels_codec_test.go @@ -234,7 +234,7 @@ func TestLabelsCodec_EncodeRequest(t *testing.T) { }, { name: "thanos labels values request", - req: &ThanosLabelsRequest{Start: 123000, End: 456000, Path: "/api/v1/label/__name__/values"}, + req: &ThanosLabelsRequest{Start: 123000, End: 456000, Path: "/api/v1/label/__name__/values", Label: "__name__"}, checkFunc: func(r *http.Request) bool { return r.URL.Query().Get(start) == startTime && r.URL.Query().Get(end) == endTime && @@ -243,7 +243,7 @@ func TestLabelsCodec_EncodeRequest(t *testing.T) { }, { name: "thanos labels values request, partial response set to true", - req: &ThanosLabelsRequest{Start: 123000, End: 456000, Path: "/api/v1/label/__name__/values", PartialResponse: true}, + req: &ThanosLabelsRequest{Start: 123000, End: 456000, Path: "/api/v1/label/__name__/values", Label: "__name__", PartialResponse: true}, checkFunc: func(r *http.Request) bool { return r.URL.Query().Get(start) == startTime && r.URL.Query().Get(end) == endTime && @@ -313,12 +313,29 @@ func TestLabelsCodec_DecodeResponse(t *testing.T) { labelsData, err := json.Marshal(labelResponse) testutil.Ok(t, err) + labelResponseWithHeaders := &ThanosLabelsResponse{ + Status: "success", + Data: []string{"__name__"}, + Headers: []*ResponseHeader{{Name: cacheControlHeader, Values: []string{noStoreValue}}}, + } + labelsDataWithHeaders, err := json.Marshal(labelResponseWithHeaders) + testutil.Ok(t, err) + seriesResponse := &ThanosSeriesResponse{ Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}, } seriesData, err := json.Marshal(seriesResponse) testutil.Ok(t, err) + + seriesResponseWithHeaders := &ThanosSeriesResponse{ + Status: "success", + Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}, + Headers: []*ResponseHeader{{Name: cacheControlHeader, Values: []string{noStoreValue}}}, + } + seriesDataWithHeaders, err := json.Marshal(seriesResponseWithHeaders) + testutil.Ok(t, err) + for _, tc := range []struct { name string expectedError error @@ -344,12 +361,34 @@ func TestLabelsCodec_DecodeResponse(t *testing.T) { res: http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBuffer(labelsData))}, expectedResponse: labelResponse, }, + { + name: "thanos labels request with HTTP headers", + req: &ThanosLabelsRequest{}, + res: http.Response{ + StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBuffer(labelsDataWithHeaders)), + Header: map[string][]string{ + cacheControlHeader: {noStoreValue}, + }, + }, + expectedResponse: labelResponseWithHeaders, + }, { name: "thanos series request", req: &ThanosSeriesRequest{}, res: http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBuffer(seriesData))}, expectedResponse: seriesResponse, }, + { + name: "thanos series request with HTTP headers", + req: &ThanosSeriesRequest{}, + res: http.Response{ + StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBuffer(seriesDataWithHeaders)), + Header: map[string][]string{ + cacheControlHeader: {noStoreValue}, + }, + }, + expectedResponse: seriesResponseWithHeaders, + }, } { t.Run(tc.name, func(t *testing.T) { // Default partial response value doesn't matter when encoding requests. @@ -364,3 +403,117 @@ func TestLabelsCodec_DecodeResponse(t *testing.T) { }) } } + +func TestLabelsCodec_MergeResponse(t *testing.T) { + for _, tc := range []struct { + name string + expectedError error + responses []queryrange.Response + expectedResponse queryrange.Response + }{ + { + name: "Prometheus range query response format, not valid", + responses: []queryrange.Response{ + &queryrange.PrometheusResponse{Status: "success"}, + }, + expectedError: httpgrpc.Errorf(http.StatusInternalServerError, "invalid response format"), + }, + { + name: "Empty response", + responses: nil, + expectedResponse: &ThanosLabelsResponse{Status: queryrange.StatusSuccess, Data: []string{}}, + }, + { + name: "One label response", + responses: []queryrange.Response{ + &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9090", "localhost:9091"}}, + }, + expectedResponse: &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9090", "localhost:9091"}}, + }, + { + name: "One label response and two empty responses", + responses: []queryrange.Response{ + &ThanosLabelsResponse{Status: queryrange.StatusSuccess, Data: []string{}}, + &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9090", "localhost:9091"}}, + &ThanosLabelsResponse{Status: queryrange.StatusSuccess, Data: []string{}}, + }, + expectedResponse: &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9090", "localhost:9091"}}, + }, + { + name: "Multiple duplicate label responses", + responses: []queryrange.Response{ + &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9090", "localhost:9091"}}, + &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9091", "localhost:9092"}}, + &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9092", "localhost:9093"}}, + }, + expectedResponse: &ThanosLabelsResponse{Status: "success", + Data: []string{"localhost:9090", "localhost:9091", "localhost:9092", "localhost:9093"}}, + }, + // This case shouldn't happen because the responses from Querier are sorted. + { + name: "Multiple unordered label responses", + responses: []queryrange.Response{ + &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9093", "localhost:9092"}}, + &ThanosLabelsResponse{Status: "success", Data: []string{"localhost:9091", "localhost:9090"}}, + }, + expectedResponse: &ThanosLabelsResponse{Status: "success", + Data: []string{"localhost:9090", "localhost:9091", "localhost:9092", "localhost:9093"}}, + }, + { + name: "One series response", + responses: []queryrange.Response{ + &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + }, + expectedResponse: &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + }, + { + name: "One series response and two empty responses", + responses: []queryrange.Response{ + &ThanosSeriesResponse{Status: queryrange.StatusSuccess}, + &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + &ThanosSeriesResponse{Status: queryrange.StatusSuccess}, + }, + expectedResponse: &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + }, + { + name: "Multiple duplicate series responses", + responses: []queryrange.Response{ + &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + }, + expectedResponse: &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{{Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}}}, + }, + { + name: "Multiple unordered series responses", + responses: []queryrange.Response{ + &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{ + {Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}, + {Labels: []labelpb.ZLabel{{Name: "test", Value: "aaa"}, {Name: "instance", Value: "localhost:9090"}}}, + }}, + &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{ + {Labels: []labelpb.ZLabel{{Name: "foo", Value: "aaa"}}}, + {Labels: []labelpb.ZLabel{{Name: "test", Value: "bbb"}, {Name: "instance", Value: "localhost:9091"}}}, + }}, + }, + expectedResponse: &ThanosSeriesResponse{Status: "success", Data: []labelpb.ZLabelSet{ + {Labels: []labelpb.ZLabel{{Name: "foo", Value: "aaa"}}}, + {Labels: []labelpb.ZLabel{{Name: "foo", Value: "bar"}}}, + {Labels: []labelpb.ZLabel{{Name: "test", Value: "aaa"}, {Name: "instance", Value: "localhost:9090"}}}, + {Labels: []labelpb.ZLabel{{Name: "test", Value: "bbb"}, {Name: "instance", Value: "localhost:9091"}}}, + }}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + // Default partial response value doesn't matter when encoding requests. + codec := NewThanosLabelsCodec(false, time.Hour*2) + r, err := codec.MergeResponse(tc.responses...) + if tc.expectedError != nil { + testutil.Equals(t, err, tc.expectedError) + } else { + testutil.Ok(t, err) + testutil.Equals(t, tc.expectedResponse, r) + } + }) + } +} diff --git a/pkg/store/labelpb/label.go b/pkg/store/labelpb/label.go index 5638f69e5f..36c5bfc139 100644 --- a/pkg/store/labelpb/label.go +++ b/pkg/store/labelpb/label.go @@ -295,3 +295,27 @@ func DeepCopy(lbls []ZLabel) []ZLabel { } return ret } + +// ZLabelSets is a sortable list of ZLabelSet. It assumes the label pairs in each ZLabelSet element are already sorted. +type ZLabelSets []ZLabelSet + +func (z ZLabelSets) Len() int { return len(z) } + +func (z ZLabelSets) Swap(i, j int) { z[i], z[j] = z[j], z[i] } + +func (z ZLabelSets) Less(i, j int) bool { + l := 0 + r := 0 + var result int + for l < z[i].Size() && r < z[j].Size() { + result = z[i].Labels[l].Compare(z[j].Labels[r]) + if result == 0 { + l++ + r++ + continue + } + return result < 0 + } + + return l == z[i].Size() +} diff --git a/pkg/store/labelpb/label_test.go b/pkg/store/labelpb/label_test.go index 6656eea445..ab8543657b 100644 --- a/pkg/store/labelpb/label_test.go +++ b/pkg/store/labelpb/label_test.go @@ -5,6 +5,8 @@ package labelpb import ( "fmt" + "reflect" + "sort" "testing" "github.com/prometheus/prometheus/pkg/labels" @@ -104,3 +106,90 @@ func BenchmarkZLabelsMarshalUnmarshal(b *testing.B) { } }) } + +func TestSortZLabelSets(t *testing.T) { + expectedResult := ZLabelSets{ + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_client_handled_total", + "cluster": "test", + "grpc_code": "OK", + "grpc_method": "Info", + }), + ), + }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_client_handled_total", + "cluster": "test", + "grpc_code": "OK", + "grpc_method": "LabelNames", + }), + ), + }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_server_handled_total", + "cluster": "test", + "grpc_code": "OK", + "grpc_method": "Info", + }), + ), + }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "up", + "instance": "localhost:10908", + }), + ), + }, + } + + list := ZLabelSets{ + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "up", + "instance": "localhost:10908", + }), + ), + }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_server_handled_total", + "cluster": "test", + "grpc_code": "OK", + "grpc_method": "Info", + }), + ), + }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_client_handled_total", + "cluster": "test", + "grpc_code": "OK", + "grpc_method": "LabelNames", + }), + ), + }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_client_handled_total", + "cluster": "test", + "grpc_code": "OK", + "grpc_method": "Info", + }), + ), + }, + } + + sort.Sort(list) + reflect.DeepEqual(expectedResult, list) +} diff --git a/test/e2e/query_frontend_test.go b/test/e2e/query_frontend_test.go index 196365a36d..7ee97b4acf 100644 --- a/test/e2e/query_frontend_test.go +++ b/test/e2e/query_frontend_test.go @@ -5,6 +5,7 @@ package e2e_test import ( "context" + "reflect" "testing" "time" @@ -262,7 +263,7 @@ func TestQueryFrontend(t *testing.T) { t.Run("query frontend splitting works for labels values API", func(t *testing.T) { labelValues(t, ctx, queryFrontend.HTTPEndpoint(), "instance", timestamp.FromTime(now.Add(-time.Hour)), timestamp.FromTime(now.Add(time.Hour)), func(res []string) bool { - return len(res) > 0 + return len(res) == 1 && res[0] == "localhost:9090" }) testutil.Ok(t, q.WaitSumMetricsWithOptions( e2e.Equals(1), @@ -281,7 +282,7 @@ func TestQueryFrontend(t *testing.T) { ) labelValues(t, ctx, queryFrontend.HTTPEndpoint(), "instance", timestamp.FromTime(now.Add(-24*time.Hour)), timestamp.FromTime(now.Add(time.Hour)), func(res []string) bool { - return len(res) > 0 + return len(res) == 1 && res[0] == "localhost:9090" }) testutil.Ok(t, q.WaitSumMetricsWithOptions( e2e.Equals(3), @@ -309,7 +310,16 @@ func TestQueryFrontend(t *testing.T) { timestamp.FromTime(now.Add(-time.Hour)), timestamp.FromTime(now.Add(time.Hour)), func(res []map[string]string) bool { - return len(res) > 0 + if len(res) != 1 { + return false + } + + return reflect.DeepEqual(res[0], map[string]string{ + "__name__": "up", + "instance": "localhost:9090", + "job": "myself", + "prometheus": "test", + }) }, ) testutil.Ok(t, q.WaitSumMetricsWithOptions( @@ -336,7 +346,16 @@ func TestQueryFrontend(t *testing.T) { timestamp.FromTime(now.Add(-24*time.Hour)), timestamp.FromTime(now.Add(time.Hour)), func(res []map[string]string) bool { - return len(res) > 0 + if len(res) != 1 { + return false + } + + return reflect.DeepEqual(res[0], map[string]string{ + "__name__": "up", + "instance": "localhost:9090", + "job": "myself", + "prometheus": "test", + }) }, ) testutil.Ok(t, q.WaitSumMetricsWithOptions( diff --git a/test/e2e/query_test.go b/test/e2e/query_test.go index 90db116f03..1658ebcfb6 100644 --- a/test/e2e/query_test.go +++ b/test/e2e/query_test.go @@ -328,7 +328,7 @@ func TestQueryLabelValues(t *testing.T) { now := time.Now() labelValues(t, ctx, q.HTTPEndpoint(), "instance", timestamp.FromTime(now.Add(-time.Hour)), timestamp.FromTime(now.Add(time.Hour)), func(res []string) bool { - return len(res) > 0 + return len(res) == 1 && res[0] == "localhost:9090" }) // Outside time range. @@ -428,7 +428,7 @@ func labelNames(t *testing.T, ctx context.Context, addr string, start, end int64 logger := log.NewLogfmtLogger(os.Stdout) logger = log.With(logger, "ts", log.DefaultTimestampUTC) - testutil.Ok(t, runutil.RetryWithLog(logger, time.Second, ctx.Done(), func() error { + testutil.Ok(t, runutil.RetryWithLog(logger, 2*time.Second, ctx.Done(), func() error { res, err := promclient.NewDefaultClient().LabelNamesInGRPC(ctx, mustURLParse(t, "http://"+addr), start, end) if err != nil { return err @@ -437,7 +437,7 @@ func labelNames(t *testing.T, ctx context.Context, addr string, start, end int64 return nil } - return errors.Errorf("unexpected results size %d", len(res)) + return errors.Errorf("unexpected results %v", res) })) } @@ -447,7 +447,7 @@ func labelValues(t *testing.T, ctx context.Context, addr, label string, start, e logger := log.NewLogfmtLogger(os.Stdout) logger = log.With(logger, "ts", log.DefaultTimestampUTC) - testutil.Ok(t, runutil.RetryWithLog(logger, time.Second, ctx.Done(), func() error { + testutil.Ok(t, runutil.RetryWithLog(logger, 2*time.Second, ctx.Done(), func() error { res, err := promclient.NewDefaultClient().LabelValuesInGRPC(ctx, mustURLParse(t, "http://"+addr), label, start, end) if err != nil { return err @@ -456,7 +456,7 @@ func labelValues(t *testing.T, ctx context.Context, addr, label string, start, e return nil } - return errors.Errorf("unexpected results size %d", len(res)) + return errors.Errorf("unexpected results %v", res) })) } @@ -465,7 +465,7 @@ func series(t *testing.T, ctx context.Context, addr string, matchers []storepb.L logger := log.NewLogfmtLogger(os.Stdout) logger = log.With(logger, "ts", log.DefaultTimestampUTC) - testutil.Ok(t, runutil.RetryWithLog(logger, time.Second, ctx.Done(), func() error { + testutil.Ok(t, runutil.RetryWithLog(logger, 2*time.Second, ctx.Done(), func() error { res, err := promclient.NewDefaultClient().SeriesInGRPC(ctx, mustURLParse(t, "http://"+addr), matchers, start, end) if err != nil { return err @@ -474,7 +474,7 @@ func series(t *testing.T, ctx context.Context, addr string, matchers []storepb.L return nil } - return errors.Errorf("unexpected results size %d", len(res)) + return errors.Errorf("unexpected results %v", res) })) } From 483e966d340944d6b0b519fa3b204fa125503e9a Mon Sep 17 00:00:00 2001 From: Bartlomiej Plotka Date: Tue, 24 Nov 2020 13:01:32 +0100 Subject: [PATCH 2/7] *: Set debug.SetPanicOnFault(true) so we can recover seg faults. (#3498) Signed-off-by: Bartlomiej Plotka --- CHANGELOG.md | 12 +++++++++++- cmd/thanos/main.go | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe5777067f..65fb9b1837 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,17 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan We use _breaking :warning:_ to mark changes that are not backward compatible (relates only to v0.y.z releases.) -## Unreleased +## [v0.17.1](https://github.com/thanos-io/thanos/releases/tag/v0.17.1) - 2020.11.24 + +### Fixed + +- [#3480](https://github.com/thanos-io/thanos/pull/3480) Query-frontend: Fixed regression. + +### Changed + +- [#3498](https://github.com/thanos-io/thanos/pull/3498) Enabled debug.SetPanicOnFault(true) which allow us to recover on queries causing SEG FAULTs (e.g unmmaped memory access). + +## [v0.17.0](https://github.com/thanos-io/thanos/releases/tag/v0.17.0) - 2020.11.18 ### Added diff --git a/cmd/thanos/main.go b/cmd/thanos/main.go index bcaf2b4a8e..cab0fc6ee2 100644 --- a/cmd/thanos/main.go +++ b/cmd/thanos/main.go @@ -11,6 +11,7 @@ import ( "os/signal" "path/filepath" "runtime" + "runtime/debug" "syscall" "github.com/go-kit/kit/log" @@ -28,6 +29,10 @@ import ( ) func main() { + // We use mmaped resources in most of the components so hardcode PanicOnFault to true. This allows us to recover (if we can e.g if queries + // are temporarily accessing unmapped memory). + debug.SetPanicOnFault(true) + if os.Getenv("DEBUG") != "" { runtime.SetMutexProfileFraction(10) runtime.SetBlockProfileRate(10) From 5cbf23e8ab07068670be53c2c95d1b34c33ea33c Mon Sep 17 00:00:00 2001 From: Matthias Loibl Date: Thu, 26 Nov 2020 12:06:46 +0100 Subject: [PATCH 3/7] Prepare v0.17.1 release (#3505) Signed-off-by: Matthias Loibl --- docs/operating/cross-cluster-tls-communication.md | 2 +- tutorials/katacoda/thanos/1-globalview/courseBase.sh | 2 +- tutorials/katacoda/thanos/1-globalview/step2.md | 8 ++++---- tutorials/katacoda/thanos/1-globalview/step3.md | 2 +- .../katacoda/thanos/7-multi-tenancy/courseBase.sh | 2 +- tutorials/katacoda/thanos/7-multi-tenancy/step1.md | 10 +++++----- tutorials/katacoda/thanos/7-multi-tenancy/step2.md | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/operating/cross-cluster-tls-communication.md b/docs/operating/cross-cluster-tls-communication.md index e2e6ed1fcc..db866b7df4 100644 --- a/docs/operating/cross-cluster-tls-communication.md +++ b/docs/operating/cross-cluster-tls-communication.md @@ -71,7 +71,7 @@ metadata: optional: false containers: - name: querier - image: 'thanosio/thanos:v0.17.0' + image: 'thanosio/thanos:v0.17.1' args: - query - '--log.level=info' diff --git a/tutorials/katacoda/thanos/1-globalview/courseBase.sh b/tutorials/katacoda/thanos/1-globalview/courseBase.sh index 99dd7e87e1..c80899b11b 100644 --- a/tutorials/katacoda/thanos/1-globalview/courseBase.sh +++ b/tutorials/katacoda/thanos/1-globalview/courseBase.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash docker pull quay.io/prometheus/prometheus:v2.16.0 -docker pull quay.io/thanos/thanos:v0.17.0 +docker pull quay.io/thanos/thanos:v0.17.1 diff --git a/tutorials/katacoda/thanos/1-globalview/step2.md b/tutorials/katacoda/thanos/1-globalview/step2.md index 4f8e424b29..22f862f16f 100644 --- a/tutorials/katacoda/thanos/1-globalview/step2.md +++ b/tutorials/katacoda/thanos/1-globalview/step2.md @@ -10,7 +10,7 @@ component and can be invoked in a single command. Let's take a look at all the Thanos commands: ``` -docker run --rm quay.io/thanos/thanos:v0.17.0 --help +docker run --rm quay.io/thanos/thanos:v0.17.1 --help ```{{execute}} You should see multiple commands that solves different purposes. @@ -53,7 +53,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus0_eu1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-eu1 \ -u root \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ sidecar \ --http-address 0.0.0.0:19090 \ --grpc-address 0.0.0.0:19190 \ @@ -68,7 +68,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus0_us1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-us1 \ -u root \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ sidecar \ --http-address 0.0.0.0:19091 \ --grpc-address 0.0.0.0:19191 \ @@ -81,7 +81,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus1_us1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-1-sidecar-us1 \ -u root \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ sidecar \ --http-address 0.0.0.0:19092 \ --grpc-address 0.0.0.0:19192 \ diff --git a/tutorials/katacoda/thanos/1-globalview/step3.md b/tutorials/katacoda/thanos/1-globalview/step3.md index 4b666db620..b3506c8122 100644 --- a/tutorials/katacoda/thanos/1-globalview/step3.md +++ b/tutorials/katacoda/thanos/1-globalview/step3.md @@ -28,7 +28,7 @@ Click below snippet to start the Querier. ``` docker run -d --net=host --rm \ --name querier \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ query \ --http-address 0.0.0.0:29090 \ --query.replica-label replica \ diff --git a/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh b/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh index fc9452241e..73ab8ced93 100644 --- a/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh +++ b/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash docker pull quay.io/prometheus/prometheus:v2.20.0 -docker pull quay.io/thanos/thanos:v0.17.0 +docker pull quay.io/thanos/thanos:v0.17.1 docker pull quay.io/thanos/prom-label-proxy:v0.3.0-rc.0-ext1 docker pull caddy:2.2.1 diff --git a/tutorials/katacoda/thanos/7-multi-tenancy/step1.md b/tutorials/katacoda/thanos/7-multi-tenancy/step1.md index 002de580b0..32dc85e3f2 100644 --- a/tutorials/katacoda/thanos/7-multi-tenancy/step1.md +++ b/tutorials/katacoda/thanos/7-multi-tenancy/step1.md @@ -88,7 +88,7 @@ docker run -d --net=host --rm \ -v $(pwd)/editor/prometheus0_fruit.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-fruit \ -u root \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ sidecar \ --http-address 0.0.0.0:19090 \ --grpc-address 0.0.0.0:19190 \ @@ -120,7 +120,7 @@ docker run -d --net=host --rm \ -v $(pwd)/editor/prometheus0_veggie.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-veggie \ -u root \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ sidecar \ --http-address 0.0.0.0:19091 \ --grpc-address 0.0.0.0:19191 \ @@ -152,7 +152,7 @@ docker run -d --net=host --rm \ -v $(pwd)/editor/prometheus1_veggie.yml:/etc/prometheus/prometheus.yml \ --name prometheus-01-sidecar-veggie \ -u root \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ sidecar \ --http-address 0.0.0.0:19092 \ --grpc-address 0.0.0.0:19192 \ @@ -170,7 +170,7 @@ Fruit: ``` docker run -d --net=host --rm \ --name querier-fruit \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ query \ --http-address 0.0.0.0:29091 \ --grpc-address 0.0.0.0:29191 \ @@ -183,7 +183,7 @@ Veggie: ``` docker run -d --net=host --rm \ --name querier-veggie \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ query \ --http-address 0.0.0.0:29092 \ --grpc-address 0.0.0.0:29192 \ diff --git a/tutorials/katacoda/thanos/7-multi-tenancy/step2.md b/tutorials/katacoda/thanos/7-multi-tenancy/step2.md index f14cdc645f..ef72ec5e85 100644 --- a/tutorials/katacoda/thanos/7-multi-tenancy/step2.md +++ b/tutorials/katacoda/thanos/7-multi-tenancy/step2.md @@ -11,7 +11,7 @@ docker stop querier-fruit && docker stop querier-veggie ``` docker run -d --net=host --rm \ --name querier-multi \ - quay.io/thanos/thanos:v0.17.0 \ + quay.io/thanos/thanos:v0.17.1 \ query \ --http-address 0.0.0.0:29090 \ --grpc-address 0.0.0.0:29190 \ From 12e5c26e1b5676fb6e348909832e1a907c37df47 Mon Sep 17 00:00:00 2001 From: Ben Ye Date: Thu, 3 Dec 2020 11:29:20 -0500 Subject: [PATCH 4/7] fix index out of bound bug when comparing ZLabelSets (#3520) * fix index out of bound bug when comparing ZLabelSets Signed-off-by: Ben Ye * fix param parsing error message Signed-off-by: Ben Ye * address comment feedbacks Signed-off-by: Ben Ye --- pkg/queryfrontend/labels_codec.go | 8 ++-- pkg/queryfrontend/queryrange_codec.go | 10 ++--- pkg/store/labelpb/label.go | 5 ++- pkg/store/labelpb/label_test.go | 57 +++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/pkg/queryfrontend/labels_codec.go b/pkg/queryfrontend/labels_codec.go index 246a8592bc..d096fe48e2 100644 --- a/pkg/queryfrontend/labels_codec.go +++ b/pkg/queryfrontend/labels_codec.go @@ -84,7 +84,7 @@ func (c labelsCodec) MergeResponse(responses ...queryrange.Response) (queryrange Data: lbls, }, nil case *ThanosSeriesResponse: - seriesData := make([]labelpb.ZLabelSet, 0) + seriesData := make(labelpb.ZLabelSets, 0) uniqueSeries := make(map[string]struct{}) for _, res := range responses { @@ -283,7 +283,7 @@ func (c labelsCodec) parseLabelsRequest(r *http.Request, op string) (queryrange. return nil, err } - result.StoreMatchers, err = parseMatchersParam(r.Form[queryv1.StoreMatcherParam]) + result.StoreMatchers, err = parseMatchersParam(r.Form, queryv1.StoreMatcherParam) if err != nil { return nil, err } @@ -317,7 +317,7 @@ func (c labelsCodec) parseSeriesRequest(r *http.Request) (queryrange.Request, er return nil, err } - result.Matchers, err = parseMatchersParam(r.Form[queryv1.MatcherParam]) + result.Matchers, err = parseMatchersParam(r.Form, queryv1.MatcherParam) if err != nil { return nil, err } @@ -336,7 +336,7 @@ func (c labelsCodec) parseSeriesRequest(r *http.Request) (queryrange.Request, er result.ReplicaLabels = r.Form[queryv1.ReplicaLabelsParam] } - result.StoreMatchers, err = parseMatchersParam(r.Form[queryv1.StoreMatcherParam]) + result.StoreMatchers, err = parseMatchersParam(r.Form, queryv1.StoreMatcherParam) if err != nil { return nil, err } diff --git a/pkg/queryfrontend/queryrange_codec.go b/pkg/queryfrontend/queryrange_codec.go index 004fb522d5..3206c28be8 100644 --- a/pkg/queryfrontend/queryrange_codec.go +++ b/pkg/queryfrontend/queryrange_codec.go @@ -111,7 +111,7 @@ func (c queryRangeCodec) DecodeRequest(_ context.Context, r *http.Request) (quer result.ReplicaLabels = r.Form[queryv1.ReplicaLabelsParam] } - result.StoreMatchers, err = parseMatchersParam(r.Form[queryv1.StoreMatcherParam]) + result.StoreMatchers, err = parseMatchersParam(r.Form, queryv1.StoreMatcherParam) if err != nil { return nil, err } @@ -221,12 +221,12 @@ func parsePartialResponseParam(s string, defaultEnablePartialResponse bool) (boo return defaultEnablePartialResponse, nil } -func parseMatchersParam(ss []string) ([][]*labels.Matcher, error) { - matchers := make([][]*labels.Matcher, 0, len(ss)) - for _, s := range ss { +func parseMatchersParam(ss url.Values, matcherParam string) ([][]*labels.Matcher, error) { + matchers := make([][]*labels.Matcher, 0, len(ss[matcherParam])) + for _, s := range ss[matcherParam] { ms, err := parser.ParseMetricSelector(s) if err != nil { - return nil, httpgrpc.Errorf(http.StatusBadRequest, errCannotParse, queryv1.StoreMatcherParam) + return nil, httpgrpc.Errorf(http.StatusBadRequest, errCannotParse, matcherParam) } matchers = append(matchers, ms) } diff --git a/pkg/store/labelpb/label.go b/pkg/store/labelpb/label.go index 36c5bfc139..ea0a7fa49b 100644 --- a/pkg/store/labelpb/label.go +++ b/pkg/store/labelpb/label.go @@ -307,7 +307,8 @@ func (z ZLabelSets) Less(i, j int) bool { l := 0 r := 0 var result int - for l < z[i].Size() && r < z[j].Size() { + lenI, lenJ := len(z[i].Labels), len(z[j].Labels) + for l < lenI && r < lenJ { result = z[i].Labels[l].Compare(z[j].Labels[r]) if result == 0 { l++ @@ -317,5 +318,5 @@ func (z ZLabelSets) Less(i, j int) bool { return result < 0 } - return l == z[i].Size() + return l == lenI } diff --git a/pkg/store/labelpb/label_test.go b/pkg/store/labelpb/label_test.go index ab8543657b..d8d258e8e1 100644 --- a/pkg/store/labelpb/label_test.go +++ b/pkg/store/labelpb/label_test.go @@ -129,6 +129,34 @@ func TestSortZLabelSets(t *testing.T) { }), ), }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_client_handled_total", + "cluster": "test", + "grpc_code": "OK", + "aa": "1", + "bb": "2", + "cc": "3", + "dd": "4", + "ee": "5", + }), + ), + }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_client_handled_total", + "cluster": "test", + "grpc_code": "OK", + "aa": "1", + "bb": "2", + "cc": "3", + "dd": "4", + "ee": "5", + }), + ), + }, { Labels: ZLabelsFromPromLabels( labels.FromMap(map[string]string{ @@ -188,6 +216,35 @@ func TestSortZLabelSets(t *testing.T) { }), ), }, + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "__name__": "grpc_client_handled_total", + "cluster": "test", + "grpc_code": "OK", + "aa": "1", + "bb": "2", + "cc": "3", + "dd": "4", + "ee": "5", + }), + ), + }, + // This label set is the same as the previous one, which should correctly return 0 in Less() function. + { + Labels: ZLabelsFromPromLabels( + labels.FromMap(map[string]string{ + "cluster": "test", + "__name__": "grpc_client_handled_total", + "grpc_code": "OK", + "aa": "1", + "bb": "2", + "cc": "3", + "dd": "4", + "ee": "5", + }), + ), + }, } sort.Sort(list) From 785de248325fe9ae30952d923cebc7296de96699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Sat, 5 Dec 2020 21:06:06 +0200 Subject: [PATCH 5/7] compact: do not cleanup blocks on boot (#3532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not cleanup blocks on boot because in some very bad cases there could be thousands of blocks ready-to-be deleted and doing that makes Thanos Compact exceed `initialDelaySeconds` on k8s. Signed-off-by: Giedrius Statkevičius --- CHANGELOG.md | 6 ++++++ cmd/thanos/compact.go | 30 ++++++++++-------------------- test/e2e/compact_test.go | 12 +++++++----- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65fb9b1837..429be3c817 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan We use _breaking :warning:_ to mark changes that are not backward compatible (relates only to v0.y.z releases.) +## [v0.17.2](https://github.com/thanos-io/thanos/releases/tag/v0.17.2) - 2020.XX.XX + +### Fixed + +- [#3532](https://github.com/thanos-io/thanos/pull/3532) compact: do not cleanup blocks on boot. Reverts the behavior change introduced in [#3115](https://github.com/thanos-io/thanos/pull/3115) as in some very bad cases the boot of Thanos Compact took a very long time since there were a lot of blocks-to-be-cleaned. + ## [v0.17.1](https://github.com/thanos-io/thanos/releases/tag/v0.17.1) - 2020.11.24 ### Fixed diff --git a/cmd/thanos/compact.go b/cmd/thanos/compact.go index 64c00ec6d8..aa4a4da7dc 100644 --- a/cmd/thanos/compact.go +++ b/cmd/thanos/compact.go @@ -113,6 +113,10 @@ func runCompact( Name: "thanos_compact_iterations_total", Help: "Total number of iterations that were executed successfully.", }) + cleanups := promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_compact_block_cleanup_loops_total", + Help: "Total number of concurrent cleanup loops of partially uploaded blocks and marked blocks that were executed successfully.", + }) partialUploadDeleteAttempts := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_compact_aborted_partial_uploads_deletion_attempts_total", Help: "Total number of started deletions of blocks that are assumed aborted and only partially uploaded.", @@ -339,29 +343,20 @@ func runCompact( cleanMtx.Lock() defer cleanMtx.Unlock() - // No need to resync before partial uploads and delete marked blocks. Last sync should be valid. + if err := sy.SyncMetas(ctx); err != nil { + cancel() + return errors.Wrap(err, "syncing metas") + } + compact.BestEffortCleanAbortedPartialUploads(ctx, logger, sy.Partial(), bkt, partialUploadDeleteAttempts, blocksCleaned, blockCleanupFailures) if err := blocksCleaner.DeleteMarkedBlocks(ctx); err != nil { return errors.Wrap(err, "cleaning marked blocks") } + cleanups.Inc() - if err := sy.SyncMetas(ctx); err != nil { - level.Error(logger).Log("msg", "failed to sync metas", "err", err) - } return nil } - // Do it once at the beginning to ensure that it runs at least once before - // the main loop. - if err := sy.SyncMetas(ctx); err != nil { - cancel() - return errors.Wrap(err, "syncing metas") - } - if err := cleanPartialMarked(); err != nil { - cancel() - return errors.Wrap(err, "cleaning partial and marked blocks") - } - compactMainFn := func() error { if err := compactor.Compact(ctx); err != nil { return errors.Wrap(err, "compaction") @@ -481,11 +476,6 @@ func runCompact( // since one iteration potentially could take a long time. if conf.cleanupBlocksInterval > 0 { g.Add(func() error { - // Wait the whole period at the beginning because we've executed this on boot. - select { - case <-time.After(conf.cleanupBlocksInterval): - case <-ctx.Done(): - } return runutil.Repeat(conf.cleanupBlocksInterval, ctx.Done(), cleanPartialMarked) }, func(error) { cancel() diff --git a/test/e2e/compact_test.go b/test/e2e/compact_test.go index b3deb8f19a..bfba33da5c 100644 --- a/test/e2e/compact_test.go +++ b/test/e2e/compact_test.go @@ -535,12 +535,14 @@ func TestCompactWithStoreGateway(t *testing.T) { c, err := e2ethanos.NewCompactor(s.SharedDir(), "expect-to-halt", svcConfig, nil) testutil.Ok(t, err) testutil.Ok(t, s.StartAndWaitReady(c)) - testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+7)), "thanos_blocks_meta_synced")) - testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) - testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified")) - // Expect compactor halted. + // Expect compactor halted and for one cleanup iteration to happen. testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(1), "thanos_compact_halted")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(1), "thanos_compact_block_cleanup_loops_total")) + + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+5)), "thanos_blocks_meta_synced")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified")) // The compact directory is still there. dataDir := filepath.Join(s.SharedDir(), "data", "compact", "expect-to-halt") @@ -559,8 +561,8 @@ func TestCompactWithStoreGateway(t *testing.T) { testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2), "thanos_compact_group_compaction_runs_completed_total")) // However, the blocks have been cleaned because that happens concurrently. - testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2), "thanos_compact_blocks_cleaned_total")) testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2), "thanos_compact_aborted_partial_uploads_deletion_attempts_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2), "thanos_compact_blocks_cleaned_total")) // Ensure bucket UI. ensureGETStatusCode(t, http.StatusOK, "http://"+path.Join(c.HTTPEndpoint(), "global")) From 616363ba8640993843da910d8d2dccfc3b9061aa Mon Sep 17 00:00:00 2001 From: Matthias Loibl Date: Mon, 7 Dec 2020 12:30:39 +0100 Subject: [PATCH 6/7] Prepare v0.17.2 (#3543) Signed-off-by: Matthias Loibl --- CHANGELOG.md | 3 ++- docs/operating/cross-cluster-tls-communication.md | 2 +- tutorials/katacoda/thanos/1-globalview/courseBase.sh | 2 +- tutorials/katacoda/thanos/1-globalview/step2.md | 8 ++++---- tutorials/katacoda/thanos/1-globalview/step3.md | 2 +- .../katacoda/thanos/7-multi-tenancy/courseBase.sh | 2 +- tutorials/katacoda/thanos/7-multi-tenancy/step1.md | 10 +++++----- tutorials/katacoda/thanos/7-multi-tenancy/step2.md | 2 +- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 429be3c817..20f79255df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,12 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan We use _breaking :warning:_ to mark changes that are not backward compatible (relates only to v0.y.z releases.) -## [v0.17.2](https://github.com/thanos-io/thanos/releases/tag/v0.17.2) - 2020.XX.XX +## [v0.17.2](https://github.com/thanos-io/thanos/releases/tag/v0.17.2) - 2020.12.07 ### Fixed - [#3532](https://github.com/thanos-io/thanos/pull/3532) compact: do not cleanup blocks on boot. Reverts the behavior change introduced in [#3115](https://github.com/thanos-io/thanos/pull/3115) as in some very bad cases the boot of Thanos Compact took a very long time since there were a lot of blocks-to-be-cleaned. +- [#3520](https://github.com/thanos-io/thanos/pull/3520) Fix index out of bound bug when comparing ZLabelSets. ## [v0.17.1](https://github.com/thanos-io/thanos/releases/tag/v0.17.1) - 2020.11.24 diff --git a/docs/operating/cross-cluster-tls-communication.md b/docs/operating/cross-cluster-tls-communication.md index db866b7df4..e80553b22d 100644 --- a/docs/operating/cross-cluster-tls-communication.md +++ b/docs/operating/cross-cluster-tls-communication.md @@ -71,7 +71,7 @@ metadata: optional: false containers: - name: querier - image: 'thanosio/thanos:v0.17.1' + image: 'thanosio/thanos:v0.17.2' args: - query - '--log.level=info' diff --git a/tutorials/katacoda/thanos/1-globalview/courseBase.sh b/tutorials/katacoda/thanos/1-globalview/courseBase.sh index c80899b11b..f6740c288f 100644 --- a/tutorials/katacoda/thanos/1-globalview/courseBase.sh +++ b/tutorials/katacoda/thanos/1-globalview/courseBase.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash docker pull quay.io/prometheus/prometheus:v2.16.0 -docker pull quay.io/thanos/thanos:v0.17.1 +docker pull quay.io/thanos/thanos:v0.17.2 diff --git a/tutorials/katacoda/thanos/1-globalview/step2.md b/tutorials/katacoda/thanos/1-globalview/step2.md index 22f862f16f..b14e0cc5bd 100644 --- a/tutorials/katacoda/thanos/1-globalview/step2.md +++ b/tutorials/katacoda/thanos/1-globalview/step2.md @@ -10,7 +10,7 @@ component and can be invoked in a single command. Let's take a look at all the Thanos commands: ``` -docker run --rm quay.io/thanos/thanos:v0.17.1 --help +docker run --rm quay.io/thanos/thanos:v0.17.2 --help ```{{execute}} You should see multiple commands that solves different purposes. @@ -53,7 +53,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus0_eu1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-eu1 \ -u root \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ sidecar \ --http-address 0.0.0.0:19090 \ --grpc-address 0.0.0.0:19190 \ @@ -68,7 +68,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus0_us1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-us1 \ -u root \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ sidecar \ --http-address 0.0.0.0:19091 \ --grpc-address 0.0.0.0:19191 \ @@ -81,7 +81,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus1_us1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-1-sidecar-us1 \ -u root \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ sidecar \ --http-address 0.0.0.0:19092 \ --grpc-address 0.0.0.0:19192 \ diff --git a/tutorials/katacoda/thanos/1-globalview/step3.md b/tutorials/katacoda/thanos/1-globalview/step3.md index b3506c8122..0238be5e8a 100644 --- a/tutorials/katacoda/thanos/1-globalview/step3.md +++ b/tutorials/katacoda/thanos/1-globalview/step3.md @@ -28,7 +28,7 @@ Click below snippet to start the Querier. ``` docker run -d --net=host --rm \ --name querier \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ query \ --http-address 0.0.0.0:29090 \ --query.replica-label replica \ diff --git a/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh b/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh index 73ab8ced93..e186a04053 100644 --- a/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh +++ b/tutorials/katacoda/thanos/7-multi-tenancy/courseBase.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash docker pull quay.io/prometheus/prometheus:v2.20.0 -docker pull quay.io/thanos/thanos:v0.17.1 +docker pull quay.io/thanos/thanos:v0.17.2 docker pull quay.io/thanos/prom-label-proxy:v0.3.0-rc.0-ext1 docker pull caddy:2.2.1 diff --git a/tutorials/katacoda/thanos/7-multi-tenancy/step1.md b/tutorials/katacoda/thanos/7-multi-tenancy/step1.md index 32dc85e3f2..686b48482c 100644 --- a/tutorials/katacoda/thanos/7-multi-tenancy/step1.md +++ b/tutorials/katacoda/thanos/7-multi-tenancy/step1.md @@ -88,7 +88,7 @@ docker run -d --net=host --rm \ -v $(pwd)/editor/prometheus0_fruit.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-fruit \ -u root \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ sidecar \ --http-address 0.0.0.0:19090 \ --grpc-address 0.0.0.0:19190 \ @@ -120,7 +120,7 @@ docker run -d --net=host --rm \ -v $(pwd)/editor/prometheus0_veggie.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-veggie \ -u root \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ sidecar \ --http-address 0.0.0.0:19091 \ --grpc-address 0.0.0.0:19191 \ @@ -152,7 +152,7 @@ docker run -d --net=host --rm \ -v $(pwd)/editor/prometheus1_veggie.yml:/etc/prometheus/prometheus.yml \ --name prometheus-01-sidecar-veggie \ -u root \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ sidecar \ --http-address 0.0.0.0:19092 \ --grpc-address 0.0.0.0:19192 \ @@ -170,7 +170,7 @@ Fruit: ``` docker run -d --net=host --rm \ --name querier-fruit \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ query \ --http-address 0.0.0.0:29091 \ --grpc-address 0.0.0.0:29191 \ @@ -183,7 +183,7 @@ Veggie: ``` docker run -d --net=host --rm \ --name querier-veggie \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ query \ --http-address 0.0.0.0:29092 \ --grpc-address 0.0.0.0:29192 \ diff --git a/tutorials/katacoda/thanos/7-multi-tenancy/step2.md b/tutorials/katacoda/thanos/7-multi-tenancy/step2.md index ef72ec5e85..85796de8a2 100644 --- a/tutorials/katacoda/thanos/7-multi-tenancy/step2.md +++ b/tutorials/katacoda/thanos/7-multi-tenancy/step2.md @@ -11,7 +11,7 @@ docker stop querier-fruit && docker stop querier-veggie ``` docker run -d --net=host --rm \ --name querier-multi \ - quay.io/thanos/thanos:v0.17.1 \ + quay.io/thanos/thanos:v0.17.2 \ query \ --http-address 0.0.0.0:29090 \ --grpc-address 0.0.0.0:29190 \ From 0a3ea99c6e2e69304cd8e00e04f253dca0ea699a Mon Sep 17 00:00:00 2001 From: Matthias Loibl Date: Wed, 9 Dec 2020 12:26:22 +0100 Subject: [PATCH 7/7] Properly rebase CHANGELOG.md after merging release-0.17 Signed-off-by: Matthias Loibl --- CHANGELOG.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f79255df..97ddd47502 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,37 +10,39 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan We use _breaking :warning:_ to mark changes that are not backward compatible (relates only to v0.y.z releases.) -## [v0.17.2](https://github.com/thanos-io/thanos/releases/tag/v0.17.2) - 2020.12.07 - -### Fixed +## Unreleased -- [#3532](https://github.com/thanos-io/thanos/pull/3532) compact: do not cleanup blocks on boot. Reverts the behavior change introduced in [#3115](https://github.com/thanos-io/thanos/pull/3115) as in some very bad cases the boot of Thanos Compact took a very long time since there were a lot of blocks-to-be-cleaned. -- [#3520](https://github.com/thanos-io/thanos/pull/3520) Fix index out of bound bug when comparing ZLabelSets. +### Added -## [v0.17.1](https://github.com/thanos-io/thanos/releases/tag/v0.17.1) - 2020.11.24 +- [#3469](https://github.com/thanos-io/thanos/pull/3469) StoreAPI: Added `hints` field to `LabelNamesRequest` and `LabelValuesRequest`. Hints in an opaque data structure that can be used to carry additional information from the store and its content is implementation specific. +- [#3421](https://github.com/thanos-io/thanos/pull/3421) Tools: Added `thanos tools bucket rewrite` command allowing to delete series from given block. ### Fixed -- [#3480](https://github.com/thanos-io/thanos/pull/3480) Query-frontend: Fixed regression. +- [#3527](https://github.com/thanos-io/thanos/pull/3527) Query Frontend: Fix query_range behavior when start/end times are the same ### Changed -- [#3498](https://github.com/thanos-io/thanos/pull/3498) Enabled debug.SetPanicOnFault(true) which allow us to recover on queries causing SEG FAULTs (e.g unmmaped memory access). +- [#3496](https://github.com/thanos-io/thanos/pull/3496) s3: Respect SignatureV2 flag for all credential providers. -## [v0.17.0](https://github.com/thanos-io/thanos/releases/tag/v0.17.0) - 2020.11.18 -### Added -- [#3469](https://github.com/thanos-io/thanos/pull/3469) StoreAPI: Added `hints` field to `LabelNamesRequest` and `LabelValuesRequest`. Hints in an opaque data structure that can be used to carry additional information from the store and its content is implementation specific. -- [#3421](https://github.com/thanos-io/thanos/pull/3421) Tools: Added `thanos tools bucket rewrite` command allowing to delete series from given block. +## [v0.17.2](https://github.com/thanos-io/thanos/releases/tag/v0.17.2) - 2020.12.07 ### Fixed -- [#3527](https://github.com/thanos-io/thanos/pull/3527) Query Frontend: Fix query_range behavior when start/end times are the same +- [#3532](https://github.com/thanos-io/thanos/pull/3532) compact: do not cleanup blocks on boot. Reverts the behavior change introduced in [#3115](https://github.com/thanos-io/thanos/pull/3115) as in some very bad cases the boot of Thanos Compact took a very long time since there were a lot of blocks-to-be-cleaned. +- [#3520](https://github.com/thanos-io/thanos/pull/3520) Fix index out of bound bug when comparing ZLabelSets. + +## [v0.17.1](https://github.com/thanos-io/thanos/releases/tag/v0.17.1) - 2020.11.24 + +### Fixed + +- [#3480](https://github.com/thanos-io/thanos/pull/3480) Query-frontend: Fixed regression. ### Changed -- [#3496](https://github.com/thanos-io/thanos/pull/3496) s3: Respect SignatureV2 flag for all credential providers. +- [#3498](https://github.com/thanos-io/thanos/pull/3498) Enabled debug.SetPanicOnFault(true) which allow us to recover on queries causing SEG FAULTs (e.g unmmaped memory access). ## [v0.17.0](https://github.com/thanos-io/thanos/releases/tag/v0.17.0) - 2020.11.18