github.com/thanos-io/thanos@v0.32.5/pkg/verifier/overlapped_blocks.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package verifier
     5  
     6  import (
     7  	"context"
     8  	"sort"
     9  
    10  	"github.com/go-kit/log/level"
    11  	"github.com/oklog/ulid"
    12  	"github.com/pkg/errors"
    13  	"github.com/prometheus/prometheus/tsdb"
    14  
    15  	"github.com/thanos-io/thanos/pkg/block"
    16  )
    17  
    18  // OverlappedBlocksIssue checks bucket for blocks with overlapped time ranges.
    19  // No repair is available for this issue.
    20  type OverlappedBlocksIssue struct{}
    21  
    22  func (OverlappedBlocksIssue) IssueID() string { return "overlapped_blocks" }
    23  
    24  func (OverlappedBlocksIssue) Verify(ctx Context, idMatcher func(ulid.ULID) bool) error {
    25  	if idMatcher != nil {
    26  		return errors.Errorf("id matching is not supported")
    27  	}
    28  
    29  	level.Info(ctx.Logger).Log("msg", "started verifying issue")
    30  
    31  	overlaps, err := fetchOverlaps(ctx, ctx.Fetcher)
    32  	if err != nil {
    33  		return errors.Wrap(err, "fetch overlaps")
    34  	}
    35  
    36  	if len(overlaps) == 0 {
    37  		// All good.
    38  		return nil
    39  	}
    40  
    41  	for k, o := range overlaps {
    42  		level.Warn(ctx.Logger).Log("msg", "found overlapped blocks", "group", k, "overlap", o)
    43  	}
    44  	return nil
    45  }
    46  
    47  func fetchOverlaps(ctx context.Context, fetcher block.MetadataFetcher) (map[string]tsdb.Overlaps, error) {
    48  	metas, _, err := fetcher.Fetch(ctx)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	groupMetasMap := map[string][]tsdb.BlockMeta{}
    54  	for _, meta := range metas {
    55  		groupKey := meta.Thanos.GroupKey()
    56  		groupMetasMap[groupKey] = append(groupMetasMap[groupKey], meta.BlockMeta)
    57  	}
    58  
    59  	overlaps := map[string]tsdb.Overlaps{}
    60  	for k, groupMetas := range groupMetasMap {
    61  
    62  		sort.Slice(groupMetas, func(i, j int) bool {
    63  			return groupMetas[i].MinTime < groupMetas[j].MinTime
    64  		})
    65  
    66  		o := tsdb.OverlappingBlocks(groupMetas)
    67  		if len(o) > 0 {
    68  			overlaps[k] = o
    69  		}
    70  	}
    71  
    72  	return overlaps, nil
    73  }