mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-08-02 22:12:41 +03:00
Compare commits
6 Commits
issue-1132
...
fix-missin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9540b01c56 | ||
|
|
a8759a539c | ||
|
|
f32b743efe | ||
|
|
8fbf865d9e | ||
|
|
80b6b56028 | ||
|
|
5bdcc5050e |
197
app/vmselect/vmui/assets/index-B1dXK3k7.js
Normal file
197
app/vmselect/vmui/assets/index-B1dXK3k7.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -37,7 +37,7 @@
|
||||
<meta property="og:title" content="UI for VictoriaMetrics">
|
||||
<meta property="og:url" content="https://victoriametrics.com/">
|
||||
<meta property="og:description" content="Explore and troubleshoot your VictoriaMetrics data">
|
||||
<script type="module" crossorigin src="./assets/index-D5egN2id.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-B1dXK3k7.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-CNC7AqOf.js">
|
||||
<link rel="modulepreload" crossorigin href="./assets/vendor-DwJYpOdw.js">
|
||||
<link rel="stylesheet" crossorigin href="./assets/vendor-CnsZ1jie.css">
|
||||
|
||||
@@ -26,33 +26,20 @@ func TestClusterSearchWithDisabledPerDayIndex(t *testing.T) {
|
||||
defer tc.Stop()
|
||||
|
||||
testSearchWithDisabledPerDayIndex(tc, func(name string, disablePerDayIndex bool) apptest.PrometheusWriteQuerier {
|
||||
// Using static ports for vmstorage because random ports may cause
|
||||
// changes in how data is sharded.
|
||||
vmstorage1 := tc.MustStartVmstorage("vmstorage1-"+name, []string{
|
||||
"-storageDataPath=" + tc.Dir() + "/vmstorage1",
|
||||
vmstorage := tc.MustStartVmstorage("vmstorage-"+name, []string{
|
||||
"-storageDataPath=" + tc.Dir() + "/vmstorage",
|
||||
"-retentionPeriod=100y",
|
||||
"-httpListenAddr=127.0.0.1:61001",
|
||||
"-vminsertAddr=127.0.0.1:61002",
|
||||
"-vmselectAddr=127.0.0.1:61003",
|
||||
fmt.Sprintf("-disablePerDayIndex=%t", disablePerDayIndex),
|
||||
})
|
||||
vmstorage2 := tc.MustStartVmstorage("vmstorage2-"+name, []string{
|
||||
"-storageDataPath=" + tc.Dir() + "/vmstorage2",
|
||||
"-retentionPeriod=100y",
|
||||
"-httpListenAddr=127.0.0.1:62001",
|
||||
"-vminsertAddr=127.0.0.1:62002",
|
||||
"-vmselectAddr=127.0.0.1:62003",
|
||||
fmt.Sprintf("-disablePerDayIndex=%t", disablePerDayIndex),
|
||||
})
|
||||
vminsert := tc.MustStartVminsert("vminsert-"+name, []string{
|
||||
"-storageNode=" + vmstorage1.VminsertAddr() + "," + vmstorage2.VminsertAddr(),
|
||||
"-storageNode=" + vmstorage.VminsertAddr(),
|
||||
})
|
||||
vmselect := tc.MustStartVmselect("vmselect"+name, []string{
|
||||
"-storageNode=" + vmstorage1.VmselectAddr() + "," + vmstorage2.VmselectAddr(),
|
||||
"-storageNode=" + vmstorage.VmselectAddr(),
|
||||
"-search.maxStalenessInterval=1m",
|
||||
})
|
||||
return &apptest.Vmcluster{
|
||||
Vmstorages: []*apptest.Vmstorage{vmstorage1, vmstorage2},
|
||||
Vmstorages: []*apptest.Vmstorage{vmstorage},
|
||||
Vminsert: vminsert,
|
||||
Vmselect: vmselect,
|
||||
}
|
||||
|
||||
@@ -829,7 +829,7 @@ See also [minimum downtime strategy](#minimum-downtime-strategy).
|
||||
|
||||
## Slowness-based re-routing
|
||||
|
||||
By default{{% available_from "#" %}}, `vminsert` automatically re-routes writes away from the slowest `vmstorage` node
|
||||
By default{{% available_from "v1.149.0" %}}, `vminsert` automatically re-routes writes away from the slowest `vmstorage` node
|
||||
to preserve maximum ingestion throughput. This prevents a single slow `vmstorage` node
|
||||
from throttling the entire cluster.
|
||||
|
||||
@@ -843,7 +843,7 @@ Disable slowness-based re-routing with `-disableRerouting=true` when keeping met
|
||||
perfectly balanced across nodes or minimizing the number of [active time series](https://docs.victoriametrics.com/victoriametrics/faq/#what-is-an-active-time-series)
|
||||
matters more than peak write throughput.
|
||||
|
||||
Slowness-based re-routing is automatically disabled{{% available_from "#" %}} when `-replicationFactor` is greater than `1`,
|
||||
Slowness-based re-routing is automatically disabled{{% available_from "v1.149.0" %}} when `-replicationFactor` is greater than `1`,
|
||||
because rerouting does not guarantee that replicated copies land on distinct storage nodes,
|
||||
which violates the replication contract.
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ VictoriaMetrics has the following prominent features:
|
||||
* Easy and fast backups from [instant snapshots](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282)
|
||||
can be done with [vmbackup](https://docs.victoriametrics.com/victoriametrics/vmbackup/) / [vmrestore](https://docs.victoriametrics.com/victoriametrics/vmrestore/) tools.
|
||||
See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-series-databases-533c1a927883) for more details.
|
||||
* It supports storage and retrieval of samples with timestamps that fall within the `[1970-01-02T00:00:00.000Z, 2262-03-31T23:59:59.999Z]` time range with millisecond precision.
|
||||
See [Retention](#retention) for details.
|
||||
* It implements a PromQL-like query language - [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/), which provides improved functionality on top of PromQL.
|
||||
* It provides a global query view. Multiple Prometheus instances or any other data sources may ingest data into VictoriaMetrics. Later this data may be queried via a single query.
|
||||
* It provides high performance and good vertical and horizontal scalability for both
|
||||
@@ -1540,6 +1542,9 @@ It is safe to extend `-retentionPeriod` on existing data. If `-retentionPeriod`
|
||||
value than before, then data outside the configured period will be eventually deleted.
|
||||
|
||||
VictoriaMetrics does not support indefinite retention, but you can specify an arbitrarily high duration, e.g. `-retentionPeriod=100y`.
|
||||
Just keep in mind that VictoriaMetrics does not support samples with negative timestamps. Timestamps at `1970-01-01` are also not
|
||||
supported because this date has a special meaning internally. It therefore rejects samples with timestamps before
|
||||
`1970-01-02T00:00:00.000Z`.
|
||||
|
||||
By default, VictoriaMetrics doesn't accept samples with timestamps bigger than `now+2d`, e.g. 2 days in the future.
|
||||
If you need accepting samples with bigger timestamps, then specify the desired "future retention" via `-futureRetention` command-line flag.
|
||||
@@ -1551,6 +1556,9 @@ For example, the following command starts VictoriaMetrics, which accepts samples
|
||||
/path/to/victoria-metrics -futureRetention=1y
|
||||
```
|
||||
|
||||
VictoriaMetrics does not support stamples after `2262-03-31T23:59:59.999Z`. If the future retention includes dates after this timestamp,
|
||||
the samples for those dates will be rejected.
|
||||
|
||||
By default, VictoriaMetrics accepts samples with timestamps as old as the configured `-retentionPeriod` allows, e.g. it accepts backfilled
|
||||
historical data as long as it fits into the retention. If you need rejecting samples with historical timestamps older than the specified
|
||||
duration, then specify the desired duration via the `-maxBackfillAge` command-line flag. This can be useful for limiting ingestion of
|
||||
|
||||
@@ -26,6 +26,10 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel
|
||||
|
||||
## tip
|
||||
|
||||
## [v1.149.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.149.0)
|
||||
|
||||
Release candidate
|
||||
|
||||
**Update Note 1:** `vminsert` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): the default value of `-disableRerouting` flag has changed from `true` to `false`, enabling [slowness-based re-routing](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/#slowness-based-re-routing) by default. Slowness re-routing is automatically disabled when `-replicationFactor` is greater than 1. If you rely on the old behavior, pass `-disableRerouting` command-line flag to `vminsert`. See [#11287](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/11287).
|
||||
|
||||
**Update Note 2:** [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): the `/api/v1/admin/tsdb/delete_series`, `/tags/delSeries` endpoints now require `POST` method. Previously, it also accepted `GET` requests. If you use `GET` requests for this endpoint, update your scripts or tooling to use `POST` instead. See [#5552](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5552).
|
||||
|
||||
@@ -688,7 +688,7 @@ Extra labels can be added to metrics collected by `vmagent` via the following me
|
||||
## Obfuscating label values
|
||||
|
||||
`vmagent` can obfuscate the values of specified labels before sending metrics to `-remoteWrite.url`
|
||||
via `-remoteWrite.obfuscateLabels`{{% available_from "#" %}}.
|
||||
via `-remoteWrite.obfuscateLabels`{{% available_from "v1.149.0" %}}.
|
||||
|
||||
This is useful when one or more `-remoteWrite.url` endpoints point to external monitoring services
|
||||
outside the organization, and sensitive label values such as `ip`, `host`, `instance`, or `datacenter`
|
||||
|
||||
@@ -480,7 +480,7 @@ Clusters here are referred to as `source` and `destination`.
|
||||
|
||||
To verify that `vmbackupmanager` is executing backup tasks normally, the following metrics can help:
|
||||
|
||||
* `vm_backup_last_success_at{type="<backup_type>"}` - unix timestamp of the last successful backup{{% available_from "#" %}}. Remains `0` if no backup has completed successfully since startup. Check error logs and verify remote storage accessibility if this persists.
|
||||
* `vm_backup_last_success_at{type="<backup_type>"}` - unix timestamp of the last successful backup{{% available_from "v1.149.0" %}}. Remains `0` if no backup has completed successfully since startup. Check error logs and verify remote storage accessibility if this persists.
|
||||
* `vm_backup_last_run_failed{type="<backup_type>"}` - whether the last backup task for the given backup type failed. The value `1` means the last task failed. Check the error logs of `vmbackupmanager` for the root cause
|
||||
* `vm_backup_errors_total{type="<backup_type>"}` - total number of backup errors for the given backup type.
|
||||
|
||||
|
||||
@@ -1290,6 +1290,9 @@ func (pt *partition) mergeParts(pws []*partWrapper, stopCh <-chan struct{}, isFi
|
||||
putBlockStreamReader(bsr)
|
||||
}
|
||||
if err != nil {
|
||||
if mpNew != nil {
|
||||
putInmemoryPart(mpNew)
|
||||
}
|
||||
return err
|
||||
}
|
||||
if mpNew != nil {
|
||||
@@ -1444,6 +1447,8 @@ func (pt *partition) openCreatedPart(ph *partHeader, pws []*partWrapper, mpNew *
|
||||
// The created part is empty. Remove it
|
||||
if mpNew == nil {
|
||||
fs.MustRemoveDir(dstPartPath)
|
||||
} else {
|
||||
putInmemoryPart(mpNew)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1118,6 +1118,14 @@ func searchAndMerge[T any](qt *querytracer.Tracer, s *Storage, tr TimeRange, sea
|
||||
qt = qt.NewChild("search indexDBs: timeRange=%v", &tr)
|
||||
defer qt.Done()
|
||||
|
||||
var zeroValue T
|
||||
if tr.MinTimestamp < minUnixMilli {
|
||||
tr.MinTimestamp = minUnixMilli
|
||||
}
|
||||
if tr.MaxTimestamp < tr.MinTimestamp {
|
||||
return zeroValue, nil
|
||||
}
|
||||
|
||||
var idbts []indexDBWithType
|
||||
|
||||
ptws := s.tb.GetPartitions(tr)
|
||||
|
||||
@@ -402,6 +402,10 @@ func TestStorageDeletePendingSeries(t *testing.T) {
|
||||
defer testRemoveAll(t)
|
||||
|
||||
const numMonths = 10
|
||||
start := time.Date(1971, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
middle := start.AddDate(0, (numMonths-1)/2, 0)
|
||||
end := start.AddDate(0, numMonths-1, 0)
|
||||
|
||||
s := MustOpenStorage(t.Name(), OpenOptions{})
|
||||
|
||||
var metricGroupName = []byte("metric")
|
||||
@@ -456,7 +460,7 @@ func TestStorageDeletePendingSeries(t *testing.T) {
|
||||
assertCountMonthsWithLabels := func(count int) {
|
||||
t.Helper()
|
||||
|
||||
ts := time.Unix(0, 0)
|
||||
ts := start
|
||||
n := 0
|
||||
for range numMonths {
|
||||
lns, err := s.SearchLabelNames(nil, nil, TimeRange{ts.UnixMilli(), ts.UnixMilli()}, 1e5, 1e9, noDeadline)
|
||||
@@ -481,7 +485,7 @@ func TestStorageDeletePendingSeries(t *testing.T) {
|
||||
var search Search
|
||||
defer search.MustClose()
|
||||
|
||||
search.Init(nil, s, []*TagFilters{tfs}, TimeRange{0, math.MaxInt64}, 1e5, noDeadline)
|
||||
search.Init(nil, s, []*TagFilters{tfs}, TimeRange{start.UnixMilli(), math.MaxInt64}, 1e5, noDeadline)
|
||||
n := 0
|
||||
for search.NextMetricBlock() {
|
||||
var b Block
|
||||
@@ -498,10 +502,6 @@ func TestStorageDeletePendingSeries(t *testing.T) {
|
||||
// Verify no metrics exist
|
||||
assertCountRows(0)
|
||||
|
||||
start := time.Unix(0, 0)
|
||||
middle := start.AddDate(0, (numMonths-1)/2, 0)
|
||||
end := start.AddDate(0, numMonths-1, 0)
|
||||
|
||||
// Add some rows and flush, so next DeleteSeries() can delete them
|
||||
addRows(start, middle, false)
|
||||
s.DebugFlush()
|
||||
@@ -3385,53 +3385,190 @@ func TestStorageQueryWithoutIndex(t *testing.T) {
|
||||
testStorageSearchWithoutIndex(t, &opts)
|
||||
}
|
||||
|
||||
func TestStorageAddRows_SamplesWithZeroDate(t *testing.T) {
|
||||
func TestStorageAddRowsWithZeroDate(t *testing.T) {
|
||||
defer testRemoveAll(t)
|
||||
|
||||
f := func(t *testing.T, disablePerDayIndex bool) {
|
||||
t.Helper()
|
||||
|
||||
s := MustOpenStorage(t.Name(), OpenOptions{
|
||||
DisablePerDayIndex: disablePerDayIndex,
|
||||
})
|
||||
defer s.MustClose()
|
||||
|
||||
mn := MetricName{MetricGroup: []byte("metric")}
|
||||
mr := MetricRow{MetricNameRaw: mn.marshalRaw(nil)}
|
||||
for range 10 {
|
||||
mr.Timestamp = rand.Int63n(msecPerDay)
|
||||
mr.Value = float64(rand.Intn(1000))
|
||||
s.AddRows([]MetricRow{mr}, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
// Reset TSID cache so that insertion takes the path that involves
|
||||
// checking whether the index contains metricName->TSID mapping.
|
||||
s.resetAndSaveTSIDCache()
|
||||
}
|
||||
|
||||
want := 1
|
||||
firstUnixDay := TimeRange{
|
||||
MinTimestamp: 0,
|
||||
MaxTimestamp: msecPerDay - 1,
|
||||
}
|
||||
if got := s.newTimeseriesCreated.Load(); got != uint64(want) {
|
||||
t.Errorf("unexpected new timeseries count: got %d, want %d", got, want)
|
||||
}
|
||||
if got := testCountAllMetricNames(s, firstUnixDay); got != want {
|
||||
t.Errorf("unexpected metric name count: got %d, want %d", got, want)
|
||||
}
|
||||
if got := testCountAllMetricIDs(s, firstUnixDay); got != want {
|
||||
t.Errorf("unexpected metric id count: got %d, want %d", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
for _, disablePerDayIndex := range []bool{false, true} {
|
||||
name := fmt.Sprintf("disablePerDayIndex=%t", disablePerDayIndex)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
f(t, disablePerDayIndex)
|
||||
testStorageAddRowsWithZeroDate(t, disablePerDayIndex)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testStorageAddRowsWithZeroDate(t *testing.T, disablePerDayIndex bool) {
|
||||
s := MustOpenStorage(t.Name(), OpenOptions{
|
||||
DisablePerDayIndex: disablePerDayIndex,
|
||||
})
|
||||
defer s.MustClose()
|
||||
|
||||
const numDays = 4
|
||||
var metricNamesAll []string
|
||||
labelNamesAll := []string{"__name__", "label"}
|
||||
var labelValuesAll []string
|
||||
mrs := make([]MetricRow, numDays)
|
||||
for day := range numDays {
|
||||
metricName := fmt.Sprintf("metric_%02d", day)
|
||||
labelName := fmt.Sprintf("label_%02d", day)
|
||||
labelValue := fmt.Sprintf("value_%02d", day)
|
||||
|
||||
if day != 0 {
|
||||
metricNamesAll = append(metricNamesAll, metricName)
|
||||
labelNamesAll = append(labelNamesAll, labelName)
|
||||
labelValuesAll = append(labelValuesAll, labelValue)
|
||||
}
|
||||
|
||||
mn := MetricName{
|
||||
MetricGroup: []byte(metricName),
|
||||
Tags: []Tag{
|
||||
{Key: []byte(labelName), Value: []byte("value")},
|
||||
{Key: []byte("label"), Value: []byte(labelValue)},
|
||||
},
|
||||
}
|
||||
mn.sortTags()
|
||||
|
||||
mrs[day].MetricNameRaw = mn.marshalRaw(nil)
|
||||
mrs[day].Timestamp = int64(day * msecPerDay)
|
||||
}
|
||||
|
||||
s.AddRows(mrs, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
if got, want := s.newTimeseriesCreated.Load(), uint64(numDays-1); got != want {
|
||||
t.Fatalf("unexpected new timeseries count: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := s.tooSmallTimestampRows.Load(), uint64(1); got != want {
|
||||
t.Fatalf("unexpected rows with too small timestamp: got %d, want %d", got, want)
|
||||
}
|
||||
|
||||
assertMetricNames := func(tr TimeRange, want []string) {
|
||||
t.Helper()
|
||||
tfs := NewTagFilters()
|
||||
if err := tfs.Add(nil, []byte("metric_.*"), false, true); err != nil {
|
||||
t.Fatalf("unexpected error in TagFilters.Add: %v", err)
|
||||
}
|
||||
got, err := s.SearchMetricNames(nil, []*TagFilters{tfs}, tr, 1e9, noDeadline)
|
||||
if err != nil {
|
||||
t.Fatalf("SearchMetricNames(%v, %v) failed unexpectedly: %v", tfs, &tr, err)
|
||||
}
|
||||
for i, name := range got {
|
||||
var mn MetricName
|
||||
if err := mn.UnmarshalString(name); err != nil {
|
||||
t.Fatalf("Could not unmarshal metric name %q: %v", name, err)
|
||||
}
|
||||
got[i] = string(mn.MetricGroup)
|
||||
}
|
||||
slices.Sort(got)
|
||||
slices.Sort(want)
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Fatalf("unexpected metric names (-want, +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
assertLabelNames := func(tr TimeRange, want []string) {
|
||||
t.Helper()
|
||||
tfs := NewTagFilters()
|
||||
if err := tfs.Add(nil, []byte("metric_.*"), false, true); err != nil {
|
||||
t.Fatalf("unexpected error in TagFilters.Add: %v", err)
|
||||
}
|
||||
got, err := s.SearchLabelNames(nil, []*TagFilters{tfs}, tr, 1e9, 1e9, noDeadline)
|
||||
if err != nil {
|
||||
t.Fatalf("SearchLabelNames(%v, %v) failed unexpectedly: %s", tfs, &tr, err)
|
||||
}
|
||||
slices.Sort(got)
|
||||
slices.Sort(want)
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Fatalf("unexpected label names (-want, +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
assertLabelValues := func(tr TimeRange, want []string) {
|
||||
t.Helper()
|
||||
tfs := NewTagFilters()
|
||||
if err := tfs.Add([]byte("label"), []byte("value_.*"), false, true); err != nil {
|
||||
t.Fatalf("unexpected error in TagFilters.Add: %v", err)
|
||||
}
|
||||
got, err := s.SearchLabelValues(nil, "label", []*TagFilters{tfs}, tr, 1e9, 1e9, noDeadline)
|
||||
if err != nil {
|
||||
t.Fatalf("SearchLabelValues(%v, %v) failed unexpectedly: %s", tfs, tr, err)
|
||||
}
|
||||
slices.Sort(got)
|
||||
slices.Sort(want)
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Fatalf("unexpected label values (-want, +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
assertData := func(tr TimeRange, want []MetricRow) {
|
||||
t.Helper()
|
||||
tfs := NewTagFilters()
|
||||
if err := tfs.Add(nil, []byte("metric_.*"), false, true); err != nil {
|
||||
t.Fatalf("TagFilters.Add() failed unexpectedly: %v", err)
|
||||
}
|
||||
if err := testAssertSearchResult(s, tr, tfs, want); err != nil {
|
||||
t.Fatalf("Search(%v, %v) failed unexpectedly: %v", tfs, tr, err)
|
||||
}
|
||||
}
|
||||
|
||||
var tr TimeRange
|
||||
|
||||
// Empty time range.
|
||||
// Expect empty search results
|
||||
tr = TimeRange{}
|
||||
assertMetricNames(tr, nil)
|
||||
assertLabelNames(tr, []string{})
|
||||
assertLabelValues(tr, []string{})
|
||||
assertData(tr, nil)
|
||||
|
||||
// First day time range.
|
||||
// Expect empty search results
|
||||
tr = TimeRange{
|
||||
MinTimestamp: 0,
|
||||
MaxTimestamp: msecPerDay - 1,
|
||||
}
|
||||
assertMetricNames(tr, nil)
|
||||
assertLabelNames(tr, []string{})
|
||||
assertLabelValues(tr, []string{})
|
||||
assertData(tr, nil)
|
||||
|
||||
// Second day time range.
|
||||
tr = TimeRange{
|
||||
MinTimestamp: msecPerDay,
|
||||
MaxTimestamp: 2*msecPerDay - 1,
|
||||
}
|
||||
if disablePerDayIndex {
|
||||
// Expect index search results for all days if per-day index is
|
||||
// disabled.
|
||||
assertMetricNames(tr, metricNamesAll)
|
||||
assertLabelNames(tr, labelNamesAll)
|
||||
assertLabelValues(tr, labelValuesAll)
|
||||
} else {
|
||||
// Expect index search results on second day only if per-day index is
|
||||
// enabled.
|
||||
assertMetricNames(tr, []string{"metric_01"})
|
||||
assertLabelNames(tr, []string{"__name__", "label", "label_01"})
|
||||
assertLabelValues(tr, []string{"value_01"})
|
||||
}
|
||||
assertData(tr, mrs[1:2])
|
||||
|
||||
// First two days time range.
|
||||
// Expect results on second day only.
|
||||
tr = TimeRange{
|
||||
MinTimestamp: 0,
|
||||
MaxTimestamp: 2*msecPerDay - 1,
|
||||
}
|
||||
if disablePerDayIndex {
|
||||
// Expect index search results for all days if per-day index is
|
||||
// disabled.
|
||||
assertMetricNames(tr, metricNamesAll)
|
||||
assertLabelNames(tr, labelNamesAll)
|
||||
assertLabelValues(tr, labelValuesAll)
|
||||
} else {
|
||||
// Expect index search results on second day only if per-day index is
|
||||
// enabled.
|
||||
assertMetricNames(tr, []string{"metric_01"})
|
||||
assertLabelNames(tr, []string{"__name__", "label", "label_01"})
|
||||
assertLabelValues(tr, []string{"value_01"})
|
||||
}
|
||||
assertData(tr, mrs[1:2])
|
||||
}
|
||||
|
||||
// testSearchMetricIDs returns metricIDs for the given tfss and tr.
|
||||
//
|
||||
// The returned metricIDs are sorted. The function panics in in case of error.
|
||||
|
||||
@@ -429,9 +429,8 @@ func (tb *table) getMinMaxIngestionTimestamps() (int64, int64) {
|
||||
func (tb *table) getMinMaxTimestampsForAge(minAgeMsecs int64) (int64, int64) {
|
||||
now := int64(fasttime.UnixTimestamp() * 1000)
|
||||
minTimestamp := now - minAgeMsecs
|
||||
if minTimestamp < 0 {
|
||||
// Negative timestamps aren't supported by the storage.
|
||||
minTimestamp = 0
|
||||
if minTimestamp < minUnixMilli {
|
||||
minTimestamp = minUnixMilli
|
||||
}
|
||||
maxTimestamp := int64(maxUnixMilli)
|
||||
if maxUnixMilli-now > tb.s.futureRetentionMsecs {
|
||||
|
||||
@@ -40,12 +40,6 @@ type TimeRange struct {
|
||||
MaxTimestamp int64
|
||||
}
|
||||
|
||||
// Zero time range and zero date are used to force global index search.
|
||||
var (
|
||||
globalIndexTimeRange = TimeRange{}
|
||||
globalIndexDate = uint64(0)
|
||||
)
|
||||
|
||||
// DateRange returns the date range for the given time range.
|
||||
func (tr *TimeRange) DateRange() (uint64, uint64) {
|
||||
minDate := uint64(tr.MinTimestamp) / msecPerDay
|
||||
@@ -117,10 +111,29 @@ func (tr *TimeRange) contains(timestamp int64) bool {
|
||||
return tr.MinTimestamp <= timestamp && timestamp <= tr.MaxTimestamp
|
||||
}
|
||||
|
||||
// Zero time range and zero date are used to force global index search.
|
||||
var (
|
||||
globalIndexDate = uint64(0)
|
||||
globalIndexTimeRange = TimeRange{}
|
||||
)
|
||||
|
||||
const (
|
||||
msecPerDay = 24 * 3600 * 1000
|
||||
msecPerHour = 3600 * 1000
|
||||
|
||||
// minUnixMilli is the min millisecond that is allowed to be used as the
|
||||
// sample timestamp.
|
||||
//
|
||||
// It corresponds to the first millisecond of the second day of the Unix
|
||||
// Epoch, i.e. 1970-01-02T00:00:00.000Z.
|
||||
//
|
||||
// The first day of the Unix Epoch is reserved: zero date and zero time
|
||||
// range are used for indicating that the the global index search is
|
||||
// required. See globalIndexDate and globalIndexTimeRange above.
|
||||
//
|
||||
// Negative timestamps aren't supported.
|
||||
minUnixMilli = msecPerDay
|
||||
|
||||
// maxUnixMilli is the max millisecond that is allowed to be used as the
|
||||
// sample timestamp.
|
||||
//
|
||||
@@ -130,6 +143,6 @@ const (
|
||||
// time.UnixMicro(math.MaxInt64/1000) == 2262-04-11 23:47:16.854775 UTC.
|
||||
//
|
||||
// Round it to the last millisecond of the last complete partition:
|
||||
// 2262-03-31 23:59:59.999 UTC.
|
||||
// 2262-03-31T23:59:59.999Z.
|
||||
maxUnixMilli = 9222422399999
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user