mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/storage/partition: prevent panic in case resulting in-memory part is empty after merge (#7329)
It is possible for in-memory part to be empty if ingested samples are removed by retention filters. In this case, data will not be discarded due to retention before creating in memory part. After in-memory parts merge samples will be removed resulting in creating completely empty part at destination. This commit checks for resulting part and skips it, if it's empty. --------- Signed-off-by: Zakhar Bessarab <z.bessarab@victoriametrics.com>
This commit is contained in:
parent
f06c7e99fe
commit
4e50d6eed3
3 changed files with 45 additions and 0 deletions
|
@ -24,6 +24,7 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/).
|
||||||
|
|
||||||
* BUGFIX: [dashboards](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/dashboards) for Single-node VictoriaMetrics, cluster: The free disk space calculation now will subtract the size of the `-storage.minFreeDiskSpaceBytes` flag to correctly display the remaining available space of Single-node VictoriaMetrics/vmstorage rather than the actual available disk space, as well as the full ETA. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7334) for the details.
|
* BUGFIX: [dashboards](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/dashboards) for Single-node VictoriaMetrics, cluster: The free disk space calculation now will subtract the size of the `-storage.minFreeDiskSpaceBytes` flag to correctly display the remaining available space of Single-node VictoriaMetrics/vmstorage rather than the actual available disk space, as well as the full ETA. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7334) for the details.
|
||||||
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert): properly set `group_name` and `file` fields for recording rules in `/api/v1/rules`.
|
* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert): properly set `group_name` and `file` fields for recording rules in `/api/v1/rules`.
|
||||||
|
* BUGFIX: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): prevent panic when ingesting samples which are outisde of configured [retention filters](https://docs.victoriametrics.com/#retention-filters). This could happen when backfilling data with retention filters which exclude samples from the backfill range.
|
||||||
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl/): fix issue with series matching for `vmctl vm-native` with `--vm-native-disable-per-metric-migration` flag enabled. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7309).
|
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl/): fix issue with series matching for `vmctl vm-native` with `--vm-native-disable-per-metric-migration` flag enabled. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7309).
|
||||||
|
|
||||||
## [v1.105.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.105.0)
|
## [v1.105.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.105.0)
|
||||||
|
|
|
@ -745,6 +745,9 @@ func (pt *partition) mustMergeInmemoryParts(pws []*partWrapper) []*partWrapper {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pw := pt.mustMergeInmemoryPartsFinal(pwsChunk)
|
pw := pt.mustMergeInmemoryPartsFinal(pwsChunk)
|
||||||
|
if pw == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
pwsResultLock.Lock()
|
pwsResultLock.Lock()
|
||||||
pwsResult = append(pwsResult, pw)
|
pwsResult = append(pwsResult, pw)
|
||||||
|
@ -806,6 +809,11 @@ func (pt *partition) mustMergeInmemoryPartsFinal(pws []*partWrapper) *partWrappe
|
||||||
}
|
}
|
||||||
mpDst.ph = *ph
|
mpDst.ph = *ph
|
||||||
|
|
||||||
|
// resulting part is empty, no need to create a part wrapper
|
||||||
|
if ph.BlocksCount == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return newPartWrapperFromInmemoryPart(mpDst, flushToDiskDeadline)
|
return newPartWrapperFromInmemoryPart(mpDst, flushToDiskDeadline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,3 +150,39 @@ func newTestPartWrappersForSizes(sizes []uint64) []*partWrapper {
|
||||||
}
|
}
|
||||||
return pws
|
return pws
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeInMemoryPartsEmptyResult(t *testing.T) {
|
||||||
|
pt := &partition{}
|
||||||
|
s := newTestStorage()
|
||||||
|
s.retentionMsecs = 1000
|
||||||
|
defer stopTestStorage(s)
|
||||||
|
pt.s = s
|
||||||
|
var pws []*partWrapper
|
||||||
|
|
||||||
|
const (
|
||||||
|
inMemoryPartsCount = 5
|
||||||
|
rowsCount = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
for range inMemoryPartsCount {
|
||||||
|
rows := make([]rawRow, rowsCount)
|
||||||
|
for i := range rowsCount {
|
||||||
|
rows[i].TSID = TSID{
|
||||||
|
MetricID: uint64(i),
|
||||||
|
}
|
||||||
|
rows[i].Value = float64(i)
|
||||||
|
rows[i].Timestamp = int64(i)
|
||||||
|
rows[i].PrecisionBits = 64
|
||||||
|
}
|
||||||
|
|
||||||
|
pws = append(pws, &partWrapper{
|
||||||
|
mp: newTestInmemoryPart(rows),
|
||||||
|
p: &part{},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pwsNew := pt.mustMergeInmemoryParts(pws)
|
||||||
|
if len(pwsNew) != 0 {
|
||||||
|
t.Fatalf("unexpected non-empty pwsNew: %d", len(pwsNew))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue