mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 13:44:05 -08:00
Allow overlapping blocks by default (#11331)
Signed-off-by: Ganesh Vernekar <ganeshvern@gmail.com>
This commit is contained in:
parent
448cfda6c1
commit
f34aeefe6e
|
@ -312,8 +312,10 @@ func main() {
|
||||||
serverOnlyFlag(a, "storage.tsdb.no-lockfile", "Do not create lockfile in data directory.").
|
serverOnlyFlag(a, "storage.tsdb.no-lockfile", "Do not create lockfile in data directory.").
|
||||||
Default("false").BoolVar(&cfg.tsdb.NoLockfile)
|
Default("false").BoolVar(&cfg.tsdb.NoLockfile)
|
||||||
|
|
||||||
serverOnlyFlag(a, "storage.tsdb.allow-overlapping-blocks", "Allow overlapping blocks, which in turn enables vertical compaction and vertical query merge.").
|
// TODO: Remove in Prometheus 3.0.
|
||||||
Default("false").BoolVar(&cfg.tsdb.AllowOverlappingBlocks)
|
var b bool
|
||||||
|
serverOnlyFlag(a, "storage.tsdb.allow-overlapping-blocks", "[DEPRECATED] This flag has no effect. Overlapping blocks are enabled by default now.").
|
||||||
|
Default("true").Hidden().BoolVar(&b)
|
||||||
|
|
||||||
serverOnlyFlag(a, "storage.tsdb.wal-compression", "Compress the tsdb WAL.").
|
serverOnlyFlag(a, "storage.tsdb.wal-compression", "Compress the tsdb WAL.").
|
||||||
Hidden().Default("true").BoolVar(&cfg.tsdb.WALCompression)
|
Hidden().Default("true").BoolVar(&cfg.tsdb.WALCompression)
|
||||||
|
@ -1008,7 +1010,6 @@ func main() {
|
||||||
"NoLockfile", cfg.tsdb.NoLockfile,
|
"NoLockfile", cfg.tsdb.NoLockfile,
|
||||||
"RetentionDuration", cfg.tsdb.RetentionDuration,
|
"RetentionDuration", cfg.tsdb.RetentionDuration,
|
||||||
"WALSegmentSize", cfg.tsdb.WALSegmentSize,
|
"WALSegmentSize", cfg.tsdb.WALSegmentSize,
|
||||||
"AllowOverlappingBlocks", cfg.tsdb.AllowOverlappingBlocks,
|
|
||||||
"WALCompression", cfg.tsdb.WALCompression,
|
"WALCompression", cfg.tsdb.WALCompression,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1531,7 +1532,6 @@ type tsdbOptions struct {
|
||||||
RetentionDuration model.Duration
|
RetentionDuration model.Duration
|
||||||
MaxBytes units.Base2Bytes
|
MaxBytes units.Base2Bytes
|
||||||
NoLockfile bool
|
NoLockfile bool
|
||||||
AllowOverlappingBlocks bool
|
|
||||||
WALCompression bool
|
WALCompression bool
|
||||||
HeadChunksWriteQueueSize int
|
HeadChunksWriteQueueSize int
|
||||||
StripeSize int
|
StripeSize int
|
||||||
|
@ -1550,8 +1550,7 @@ func (opts tsdbOptions) ToTSDBOptions() tsdb.Options {
|
||||||
RetentionDuration: int64(time.Duration(opts.RetentionDuration) / time.Millisecond),
|
RetentionDuration: int64(time.Duration(opts.RetentionDuration) / time.Millisecond),
|
||||||
MaxBytes: int64(opts.MaxBytes),
|
MaxBytes: int64(opts.MaxBytes),
|
||||||
NoLockfile: opts.NoLockfile,
|
NoLockfile: opts.NoLockfile,
|
||||||
AllowOverlappingCompaction: opts.AllowOverlappingBlocks,
|
AllowOverlappingCompaction: true,
|
||||||
AllowOverlappingQueries: opts.AllowOverlappingBlocks,
|
|
||||||
WALCompression: opts.WALCompression,
|
WALCompression: opts.WALCompression,
|
||||||
HeadChunksWriteQueueSize: opts.HeadChunksWriteQueueSize,
|
HeadChunksWriteQueueSize: opts.HeadChunksWriteQueueSize,
|
||||||
StripeSize: opts.StripeSize,
|
StripeSize: opts.StripeSize,
|
||||||
|
|
|
@ -117,8 +117,6 @@ func TestBackfillRuleIntegration(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := tsdb.DefaultOptions()
|
opts := tsdb.DefaultOptions()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
db, err := tsdb.Open(tmpDir, nil, nil, opts, nil)
|
db, err := tsdb.Open(tmpDir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -246,8 +244,6 @@ func TestBackfillLabels(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := tsdb.DefaultOptions()
|
opts := tsdb.DefaultOptions()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
db, err := tsdb.Open(tmpDir, nil, nil, opts, nil)
|
db, err := tsdb.Open(tmpDir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ Backfilling can be used via the Promtool command line. Promtool will write the b
|
||||||
promtool tsdb create-blocks-from openmetrics <input file> [<output directory>]
|
promtool tsdb create-blocks-from openmetrics <input file> [<output directory>]
|
||||||
```
|
```
|
||||||
|
|
||||||
After the creation of the blocks, move it to the data directory of Prometheus. If there is an overlap with the existing blocks in Prometheus, the flag `--storage.tsdb.allow-overlapping-blocks` needs to be set. Note that any backfilled data is subject to the retention configured for your Prometheus server (by time or size).
|
After the creation of the blocks, move it to the data directory of Prometheus. If there is an overlap with the existing blocks in Prometheus, the flag `--storage.tsdb.allow-overlapping-blocks` needs to be set for Prometheus versions v2.38 and below. Note that any backfilled data is subject to the retention configured for your Prometheus server (by time or size).
|
||||||
|
|
||||||
#### Longer Block Durations
|
#### Longer Block Durations
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ $ promtool tsdb create-blocks-from rules \
|
||||||
|
|
||||||
The recording rule files provided should be a normal [Prometheus rules file](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/).
|
The recording rule files provided should be a normal [Prometheus rules file](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/).
|
||||||
|
|
||||||
The output of `promtool tsdb create-blocks-from rules` command is a directory that contains blocks with the historical rule data for all rules in the recording rule files. By default the output directory is `data/`. In order to make use of this new block data, the blocks must be moved to a running Prometheus instance data dir `storage.tsdb.path` that has the flag `--storage.tsdb.allow-overlapping-blocks` enabled. Once moved, the new blocks will merge with existing blocks when the next compaction runs.
|
The output of `promtool tsdb create-blocks-from rules` command is a directory that contains blocks with the historical rule data for all rules in the recording rule files. By default, the output directory is `data/`. In order to make use of this new block data, the blocks must be moved to a running Prometheus instance data dir `storage.tsdb.path` (for Prometheus versions v2.38 and below, the flag `--storage.tsdb.allow-overlapping-blocks` must be enabled). Once moved, the new blocks will merge with existing blocks when the next compaction runs.
|
||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
|
|
42
tsdb/db.go
42
tsdb/db.go
|
@ -76,8 +76,7 @@ func DefaultOptions() *Options {
|
||||||
MinBlockDuration: DefaultBlockDuration,
|
MinBlockDuration: DefaultBlockDuration,
|
||||||
MaxBlockDuration: DefaultBlockDuration,
|
MaxBlockDuration: DefaultBlockDuration,
|
||||||
NoLockfile: false,
|
NoLockfile: false,
|
||||||
AllowOverlappingCompaction: false,
|
AllowOverlappingCompaction: true,
|
||||||
AllowOverlappingQueries: false,
|
|
||||||
WALCompression: false,
|
WALCompression: false,
|
||||||
StripeSize: DefaultStripeSize,
|
StripeSize: DefaultStripeSize,
|
||||||
HeadChunksWriteBufferSize: chunks.DefaultWriteBufferSize,
|
HeadChunksWriteBufferSize: chunks.DefaultWriteBufferSize,
|
||||||
|
@ -114,18 +113,12 @@ type Options struct {
|
||||||
// NoLockfile disables creation and consideration of a lock file.
|
// NoLockfile disables creation and consideration of a lock file.
|
||||||
NoLockfile bool
|
NoLockfile bool
|
||||||
|
|
||||||
// Querying on overlapping blocks are allowed if AllowOverlappingQueries is true.
|
|
||||||
// Since querying is a required operation for TSDB, if there are going to be
|
|
||||||
// overlapping blocks, then this should be set to true.
|
|
||||||
// NOTE: Do not use this directly in DB. Use it via DB.AllowOverlappingQueries().
|
|
||||||
AllowOverlappingQueries bool
|
|
||||||
|
|
||||||
// Compaction of overlapping blocks are allowed if AllowOverlappingCompaction is true.
|
// Compaction of overlapping blocks are allowed if AllowOverlappingCompaction is true.
|
||||||
// This is an optional flag for overlapping blocks.
|
// This is an optional flag for overlapping blocks.
|
||||||
// The reason why this flag exists is because there are various users of the TSDB
|
// The reason why this flag exists is because there are various users of the TSDB
|
||||||
// that do not want vertical compaction happening on ingest time. Instead,
|
// that do not want vertical compaction happening on ingest time. Instead,
|
||||||
// they'd rather keep overlapping blocks and let another component do the overlapping compaction later.
|
// they'd rather keep overlapping blocks and let another component do the overlapping compaction later.
|
||||||
// For Prometheus, this will always be enabled if overlapping queries is enabled.
|
// For Prometheus, this will always be true.
|
||||||
AllowOverlappingCompaction bool
|
AllowOverlappingCompaction bool
|
||||||
|
|
||||||
// WALCompression will turn on Snappy compression for records on the WAL.
|
// WALCompression will turn on Snappy compression for records on the WAL.
|
||||||
|
@ -642,9 +635,6 @@ func validateOpts(opts *Options, rngs []int64) (*Options, []int64) {
|
||||||
if opts.MinBlockDuration > opts.MaxBlockDuration {
|
if opts.MinBlockDuration > opts.MaxBlockDuration {
|
||||||
opts.MaxBlockDuration = opts.MinBlockDuration
|
opts.MaxBlockDuration = opts.MinBlockDuration
|
||||||
}
|
}
|
||||||
if opts.OutOfOrderTimeWindow > 0 {
|
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
}
|
|
||||||
if opts.OutOfOrderCapMax <= 0 {
|
if opts.OutOfOrderCapMax <= 0 {
|
||||||
opts.OutOfOrderCapMax = DefaultOutOfOrderCapMax
|
opts.OutOfOrderCapMax = DefaultOutOfOrderCapMax
|
||||||
}
|
}
|
||||||
|
@ -1368,11 +1358,6 @@ func (db *DB) reloadBlocks() (err error) {
|
||||||
sort.Slice(toLoad, func(i, j int) bool {
|
sort.Slice(toLoad, func(i, j int) bool {
|
||||||
return toLoad[i].Meta().MinTime < toLoad[j].Meta().MinTime
|
return toLoad[i].Meta().MinTime < toLoad[j].Meta().MinTime
|
||||||
})
|
})
|
||||||
if !db.AllowOverlappingQueries() {
|
|
||||||
if err := validateBlockSequence(toLoad); err != nil {
|
|
||||||
return errors.Wrap(err, "invalid block sequence")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap new blocks first for subsequently created readers to be seen.
|
// Swap new blocks first for subsequently created readers to be seen.
|
||||||
oldBlocks := db.blocks
|
oldBlocks := db.blocks
|
||||||
|
@ -1398,10 +1383,6 @@ func (db *DB) reloadBlocks() (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) AllowOverlappingQueries() bool {
|
|
||||||
return db.opts.AllowOverlappingQueries || db.oooWasEnabled.Load()
|
|
||||||
}
|
|
||||||
|
|
||||||
func openBlocks(l log.Logger, dir string, loaded []*Block, chunkPool chunkenc.Pool) (blocks []*Block, corrupted map[ulid.ULID]error, err error) {
|
func openBlocks(l log.Logger, dir string, loaded []*Block, chunkPool chunkenc.Pool) (blocks []*Block, corrupted map[ulid.ULID]error, err error) {
|
||||||
bDirs, err := blockDirs(dir)
|
bDirs, err := blockDirs(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1548,25 +1529,6 @@ func (db *DB) deleteBlocks(blocks map[ulid.ULID]*Block) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateBlockSequence returns error if given block meta files indicate that some blocks overlaps within sequence.
|
|
||||||
func validateBlockSequence(bs []*Block) error {
|
|
||||||
if len(bs) <= 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var metas []BlockMeta
|
|
||||||
for _, b := range bs {
|
|
||||||
metas = append(metas, b.meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
overlaps := OverlappingBlocks(metas)
|
|
||||||
if len(overlaps) > 0 {
|
|
||||||
return errors.Errorf("block time ranges overlap: %s", overlaps)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeRange specifies minTime and maxTime range.
|
// TimeRange specifies minTime and maxTime range.
|
||||||
type TimeRange struct {
|
type TimeRange struct {
|
||||||
Min, Max int64
|
Min, Max int64
|
||||||
|
|
|
@ -3976,8 +3976,6 @@ func TestOOOCompaction(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -4158,8 +4156,6 @@ func TestOOOCompactionWithNormalCompaction(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -4255,7 +4251,6 @@ func Test_Querier_OOOQuery(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 24 * time.Hour.Milliseconds()
|
opts.OutOfOrderTimeWindow = 24 * time.Hour.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = false
|
opts.AllowOverlappingCompaction = false
|
||||||
|
|
||||||
series1 := labels.FromStrings("foo", "bar1")
|
series1 := labels.FromStrings("foo", "bar1")
|
||||||
|
@ -4341,7 +4336,6 @@ func Test_ChunkQuerier_OOOQuery(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 24 * time.Hour.Milliseconds()
|
opts.OutOfOrderTimeWindow = 24 * time.Hour.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = false
|
opts.AllowOverlappingCompaction = false
|
||||||
|
|
||||||
series1 := labels.FromStrings("foo", "bar1")
|
series1 := labels.FromStrings("foo", "bar1")
|
||||||
|
@ -4435,7 +4429,6 @@ func TestOOOAppendAndQuery(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 4 * time.Hour.Milliseconds()
|
opts.OutOfOrderTimeWindow = 4 * time.Hour.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
|
|
||||||
db := openTestDB(t, opts, nil)
|
db := openTestDB(t, opts, nil)
|
||||||
db.DisableCompactions()
|
db.DisableCompactions()
|
||||||
|
@ -4627,7 +4620,6 @@ func TestWBLAndMmapReplay(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 4 * time.Hour.Milliseconds()
|
opts.OutOfOrderTimeWindow = 4 * time.Hour.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
|
|
||||||
db := openTestDB(t, opts, nil)
|
db := openTestDB(t, opts, nil)
|
||||||
db.DisableCompactions()
|
db.DisableCompactions()
|
||||||
|
@ -4815,8 +4807,6 @@ func TestOOOCompactionFailure(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -4956,8 +4946,6 @@ func TestWBLCorruption(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 30
|
opts.OutOfOrderCapMax = 30
|
||||||
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -5104,8 +5092,6 @@ func TestOOOMmapCorruption(t *testing.T) {
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderCapMax = 10
|
opts.OutOfOrderCapMax = 10
|
||||||
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 300 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -5563,8 +5549,6 @@ func TestWblReplayAfterOOODisableAndRestart(t *testing.T) {
|
||||||
|
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderTimeWindow = 60 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 60 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
opts.AllowOverlappingCompaction = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -5624,7 +5608,6 @@ func TestPanicOnApplyConfig(t *testing.T) {
|
||||||
|
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderTimeWindow = 60 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 60 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -5673,7 +5656,6 @@ func TestDiskFillingUpAfterDisablingOOO(t *testing.T) {
|
||||||
|
|
||||||
opts := DefaultOptions()
|
opts := DefaultOptions()
|
||||||
opts.OutOfOrderTimeWindow = 60 * time.Minute.Milliseconds()
|
opts.OutOfOrderTimeWindow = 60 * time.Minute.Milliseconds()
|
||||||
opts.AllowOverlappingQueries = true
|
|
||||||
|
|
||||||
db, err := Open(dir, nil, nil, opts, nil)
|
db, err := Open(dir, nil, nil, opts, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
Loading…
Reference in a new issue