From f8a39767a43eee03396912a3b6028bd4b9a88284 Mon Sep 17 00:00:00 2001 From: Carrie Edwards Date: Tue, 26 Nov 2024 11:14:09 -0800 Subject: [PATCH] Update WAL doc to include native histogram encodings --- tsdb/docs/format/wal.md | 216 +++++++++++++++++++++++++++++++++++----- tsdb/head_append.go | 1 + tsdb/head_wal.go | 5 +- 3 files changed, 192 insertions(+), 30 deletions(-) diff --git a/tsdb/docs/format/wal.md b/tsdb/docs/format/wal.md index 835ede4113..092999a53a 100644 --- a/tsdb/docs/format/wal.md +++ b/tsdb/docs/format/wal.md @@ -79,32 +79,6 @@ The first sample record begins at the second row. └──────────────────────────────────────────────────────────────────┘ ``` -### Native histogram records - -Native histogram records are encoded as - -``` -┌──────────────────────────────────────────────────────────────────┐ -│ type = 2 <1b> │ -├──────────────────────────────────────────────────────────────────┤ -│ ┌────────────────────┬───────────────────────────┐ │ -│ │ id <8b> │ timestamp <8b> │ │ -│ └────────────────────┴───────────────────────────┘ │ -│ ┌────────────────────┬───────────────────────────┬ │ -│ │ id_delta │ timestamp_delta │ │ -│ ├────────────────────┴───────────────────────────┴─────────────┤ │ -│ │ n = len(labels) │ │ -│ ├──────────────────────┬───────────────────────────────────────┤ │ -│ │ len(str_1) │ str_1 │ │ -│ ├──────────────────────┴───────────────────────────────────────┤ │ -│ │ ... │ │ -│ ├───────────────────────┬──────────────────────────────────────┤ │ -│ │ len(str_2n) │ str_2n │ │ │ -│ └───────────────────────┴────────────────┴─────────────────────┘ │ -│ . . . │ -└──────────────────────────────────────────────────────────────────┘ -``` - ### Tombstone records Tombstone records encode tombstones as a list of triples `(series_id, min_time, max_time)` @@ -182,3 +156,193 @@ Metadata records encode the metadata updates associated with a series. └────────────────────────────────────────────┘ ``` +### Native histogram records + +Native histogram records are encoded as a list of histogram samples. +Series reference and timestamp are encoded as deltas w.r.t the first histogram sample. +The first row stores the starting id and the starting timestamp. +The first native histogram sample record begins at the second row. + +There are several different types of native histogram samples. + +Integer histogram encoding: + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ type = 9 <1b> │ +├──────────────────────────────────────────────────────────────────┤ +│ ┌────────────────────┬───────────────────────────┐ │ +│ │ id <8b> │ timestamp <8b> │ │ +│ └────────────────────┴───────────────────────────┘ │ +│ ┌────────────────────┬───────────────────────────┬ │ +│ │ id_delta │ timestamp_delta │ │ +│ ├────────────────────┴────┬──────────────────────┤ │ +│ │ counter_reset_hint <8b> │ schema │ │ +│ ├──────────────────────┬──┴──────────────────────┤ │ +│ │ zero_threshold <8b> │ zero_count │ │ +│ ├──────────────────────┴┬────────────────────────┤ │ +│ │ count │ sum │ │ +│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │ +│ │ len(positive_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(positive_buckets) │ bucket_count │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_buckets) │ bucket_count │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ └────────────────────────────────┴─────────────────────────────┘ │ +│ . . . │ +└──────────────────────────────────────────────────────────────────┘ +``` + +There are also integer histograms that have custom buckets, which will always +have a schem of 053. Custom bucket native histograms additionally encode +a field that specifies the custom values: + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ type = 9 <1b> │ +├──────────────────────────────────────────────────────────────────┤ +│ ┌────────────────────┬───────────────────────────┐ │ +│ │ id <8b> │ timestamp <8b> │ │ +│ └────────────────────┴───────────────────────────┘ │ +│ ┌────────────────────┬───────────────────────────┬ │ +│ │ id_delta │ timestamp_delta │ │ +│ ├────────────────────┴────┬──────────────────────┤ │ +│ │ counter_reset_hint <8b> │ schema │ │ +│ ├──────────────────────┬──┴──────────────────────┤ │ +│ │ zero_threshold <8b> │ zero_count │ │ +│ ├──────────────────────┴┬────────────────────────┤ │ +│ │ count │ sum │ │ +│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │ +│ │ len(positive_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(positive_buckets) │ bucket_count │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_buckets) │ bucket_count │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(custom_values) │ value <8b> │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ └────────────────────────────────┴─────────────────────────────┘ │ +│ . . . │ +└──────────────────────────────────────────────────────────────────┘ +``` + +(Note: negative spans and negative buckets will be empty for custom bucket native histograms.) + +Float histogram encoding: + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ type = 10 <1b> │ +├──────────────────────────────────────────────────────────────────┤ +│ ┌────────────────────┬───────────────────────────┐ │ +│ │ id <8b> │ timestamp <8b> │ │ +│ └────────────────────┴───────────────────────────┘ │ +│ ┌────────────────────┬───────────────────────────┐ │ +│ │ id_delta │ timestamp_delta │ │ +│ ├────────────────────┴────┬──────────────────────┤ │ +│ │ counter_reset_hint <8b> │ schema │ │ +│ ├──────────────────────┬──┴──────────────────────┤ │ +│ │ zero_threshold <8b> │ zero_count <8b> │ │ +│ ├──────────────────────┴┬────────────────────────┤ │ +│ │ count <8b> │ sum <8b> │ │ +│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │ +│ │ len(positive_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(positive_buckets) │ bucket_count <8b> │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_buckets) │ bucket_count <8b> │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ └────────────────────────────────┴─────────────────────────────┘ │ +│ . . . │ +└──────────────────────────────────────────────────────────────────┘ +``` + +There are also float histograms with custom buckets. + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ type = 10 <1b> │ +├──────────────────────────────────────────────────────────────────┤ +│ ┌────────────────────┬───────────────────────────┐ │ +│ │ id <8b> │ timestamp <8b> │ │ +│ └────────────────────┴───────────────────────────┘ │ +│ ┌────────────────────┬───────────────────────────┐ │ +│ │ id_delta │ timestamp_delta │ │ +│ ├────────────────────┴────┬──────────────────────┤ │ +│ │ counter_reset_hint <8b> │ schema │ │ +│ ├──────────────────────┬──┴──────────────────────┤ │ +│ │ zero_threshold <8b> │ zero_count <8b> │ │ +│ ├──────────────────────┴┬────────────────────────┤ │ +│ │ count <8b> │ sum <8b> │ │ +│ ├───────────────────────┴────────┬───────────────┴─────────────┐ │ +│ │ len(positive_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_spans) │ offset │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ length │ │ +│ │ ├─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(positive_buckets) │ bucket_count <8b> │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(negative_buckets) │ bucket_count <8b> │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ len(custom_values) │ value <8b> │ │ +│ ├────────────────────────────────┼─────────────────────────────┤ │ +│ │ │ . . . │ │ +│ └────────────────────────────────┴─────────────────────────────┘ │ +│ . . . │ +└──────────────────────────────────────────────────────────────────┘ +``` + +(Note: negative spans and negative buckets will also be empty for custom bucket float native histograms.) diff --git a/tsdb/head_append.go b/tsdb/head_append.go index 7dacb9037b..1cac44e160 100644 --- a/tsdb/head_append.go +++ b/tsdb/head_append.go @@ -691,6 +691,7 @@ func (a *headAppender) AppendHistogram(ref storage.SeriesRef, lset labels.Labels if created && s.lastHistogramValue == nil && s.lastFloatHistogramValue == nil { s.lastHistogramValue = &histogram.Histogram{} } + // TODO(codesome): If we definitely know at this point that the sample is ooo, then optimise // to skip that sample from the WAL and write only in the WBL. _, delta, err := s.appendableHistogram(t, h, a.headMaxt, a.minValidTime, a.oooTimeWindow, a.head.opts.EnableOOONativeHistograms.Load()) diff --git a/tsdb/head_wal.go b/tsdb/head_wal.go index 458162522b..d71dc9d33d 100644 --- a/tsdb/head_wal.go +++ b/tsdb/head_wal.go @@ -58,7 +58,6 @@ func (h *Head) loadWAL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch var unknownExemplarRefs atomic.Uint64 var unknownHistogramRefs atomic.Uint64 var unknownMetadataRefs atomic.Uint64 - // Track number of series records that had overlapping m-map chunks. var mmapOverlappingChunks atomic.Uint64 @@ -139,8 +138,7 @@ func (h *Head) loadWAL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch dec := record.NewDecoder(syms) for r.Next() { rec := r.Record() - recType := dec.Type(rec) - switch recType { + switch dec.Type(rec) { case record.Series: series := seriesPool.Get()[:0] series, err = dec.Series(rec, series) @@ -618,7 +616,6 @@ func (wp *walSubsetProcessor) processWALSamples(h *Head, mmappedChunks, oooMmapp if s.t <= ms.mmMaxTime { continue } - var chunkCreated bool if s.h != nil { _, chunkCreated = ms.appendHistogram(s.t, s.h, 0, appendChunkOpts)