diff --git a/lib/storage/storage.go b/lib/storage/storage.go index bfd73989e..1f93c4baf 100644 --- a/lib/storage/storage.go +++ b/lib/storage/storage.go @@ -595,7 +595,10 @@ func nextRetentionDuration(retentionMonths int) time.Duration { n -= n % retentionMonths y := n / 12 m := time.Month((n % 12) + 1) - deadline := time.Date(y, m, 1, 0, 0, 0, 0, time.UTC) + // Schedule the deadline to +4 hours from the next retention period start. + // This should prevent from possible double deletion of indexdb + // due to time drift - see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/248 . + deadline := time.Date(y, m, 1, 4, 0, 0, 0, time.UTC) return deadline.Sub(t) } diff --git a/lib/storage/storage_test.go b/lib/storage/storage_test.go index cf408170e..da07e89f5 100644 --- a/lib/storage/storage_test.go +++ b/lib/storage/storage_test.go @@ -306,10 +306,9 @@ func TestMetricRowMarshalUnmarshal(t *testing.T) { func TestNextRetentionDuration(t *testing.T) { for retentionMonths := 1; retentionMonths < 360; retentionMonths++ { - currTime := time.Now().UTC() - d := nextRetentionDuration(retentionMonths) - if d < 0 { + if d <= 0 { + currTime := time.Now().UTC() nextTime := time.Now().UTC().Add(d) t.Fatalf("unexected retention duration for retentionMonths=%d; got %s; must be %s + %d months", retentionMonths, nextTime, currTime, retentionMonths) }