Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* [CHANGE] Limits: removed the experimental `cost_attribution_labels` configuration option. Use `cost_attribution_labels_structured` instead. #13286
* [CHANGE] Ingester: Renamed `cortex_ingest_storage_writer_buffered_produce_bytes` metric to `cortex_ingest_storage_writer_buffered_produce_bytes_distribution` (Prometheus summary), and added `cortex_ingest_storage_writer_buffered_produce_bytes` metric that exports the buffer size as a Prometheus Gauge. #13414
* [CHANGE] Querier and query-frontend: Removed support for per-step stats when MQE is enabled. #13582
* [CHANGE] Compactor: Require that uploaded TSDB blocks use v2 of the index file format. #13815
* [CHANGE] Query-frontend: Removed support for calculating 'cache-adjusted samples processed' query statistic. The `-query-frontend.cache-samples-processed-stats` CLI flag has been deprecated and will be removed in a future release. Setting it has now no effect. #13582
* [CHANGE] Querier: Renamed experimental flag `-querier.prefer-availability-zone` to `-querier.prefer-availability-zones` and changed it to accept a comma-separated list of availability zones. All zones in the list are given equal priority when querying ingesters and store-gateways. #13756 #13758
* [CHANGE] Ingester: Stabilize experimental flag `-ingest-storage.write-logs-fsync-before-kafka-commit-concurrency` to fsync write logs before the offset is committed to Kafka. Remove `-ingest-storage.write-logs-fsync-before-kafka-commit-enabled` since this is always enabled now. #13591
Expand Down
24 changes: 24 additions & 0 deletions pkg/storage/tsdb/block/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ import (
util_log "github.com/grafana/mimir/pkg/util/log"
)

var (
SupportedIndexFormats = []int{index.FormatV2}
)

// VerifyBlock does a full run over a block index and chunk data and verifies that they fulfill the order invariants.
func VerifyBlock(ctx context.Context, logger log.Logger, blockDir string, minTime, maxTime int64, checkChunks bool) error {
stats, err := GatherBlockHealthStats(ctx, logger, blockDir, minTime, maxTime, checkChunks)
Expand All @@ -44,6 +48,9 @@ func VerifyBlock(ctx context.Context, logger log.Logger, blockDir string, minTim
}

type HealthStats struct {
// IndexFormat is the format version used by the TSDB index file.
IndexFormat int

// TotalSeries represents total number of series in block.
TotalSeries int64
// OutOfOrderSeries represents number of series that have out of order chunks.
Expand All @@ -68,6 +75,17 @@ type HealthStats struct {
OutOfOrderLabels int
}

// UnsupportedIndexFormat returns an error if the stats indicate this TSDB block uses
// an index format that isn't supported by the read path (store-gateways use a custom
// implementation of TSDB index parsing code, to avoid mmap, which only supports v2).
func (i HealthStats) UnsupportedIndexFormat() error {
if !slices.Contains(SupportedIndexFormats, i.IndexFormat) {
return fmt.Errorf("index uses format %d which is not supported (%v are supported)", i.IndexFormat, SupportedIndexFormats)
}

return nil
}

// OutOfOrderLabelsErr returns an error if the HealthStats object indicates
// postings without of order labels. This is corrected by Prometheus Issue
// #5372 and affects Prometheus versions 2.8.0 and below.
Expand Down Expand Up @@ -129,6 +147,10 @@ func (i HealthStats) AnyErr() error {
errMsg = append(errMsg, err.Error())
}

if err := i.UnsupportedIndexFormat(); err != nil {
errMsg = append(errMsg, err.Error())
}

if err := i.Issue347OutsideChunksErr(); err != nil {
errMsg = append(errMsg, err.Error())
}
Expand Down Expand Up @@ -162,6 +184,8 @@ func GatherBlockHealthStats(ctx context.Context, logger log.Logger, blockDir str
}
defer runutil.CloseWithErrCapture(&err, r, "gather index issue file reader")

stats.IndexFormat = r.Version()

n, v := index.AllPostingsKey()
p, err := r.Postings(ctx, n, v)
if err != nil {
Expand Down
71 changes: 71 additions & 0 deletions pkg/storage/tsdb/block/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,77 @@ import (
"github.com/stretchr/testify/require"
)

func TestHealthStats_AnyErr(t *testing.T) {
testCases := []struct {
name string
stats HealthStats
expectSuccess bool
}{
{
name: "critical error",
stats: HealthStats{
IndexFormat: index.FormatV2,
OutsideChunks: 1,
CompleteOutsideChunks: 1,
},
expectSuccess: false,
},
{
name: "invalid index version",
stats: HealthStats{
IndexFormat: index.FormatV1,
},
expectSuccess: false,
},
{
name: "issue 347 outside chunks",
stats: HealthStats{
IndexFormat: index.FormatV2,
OutsideChunks: 1,
Issue347OutsideChunks: 1,
},
expectSuccess: false,
},
{
name: "out of order labels",
stats: HealthStats{
IndexFormat: index.FormatV2,
OutOfOrderLabels: 1,
},
expectSuccess: false,
},

{
name: "out of order chunks",
stats: HealthStats{
IndexFormat: index.FormatV2,
TotalSeries: 100,
OutOfOrderSeries: 50,
OutOfOrderChunks: 10,
},
expectSuccess: false,
},
{
name: "success",
stats: HealthStats{
IndexFormat: index.FormatV2,
},
expectSuccess: true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.stats.AnyErr()
if tc.expectSuccess {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
}

func TestRewrite(t *testing.T) {
const excludeTime int64 = 600

Expand Down