2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-29 08:14:03 +00:00

Merge pull request #4366 from gautammenghani/master

Issue #3624: Preserve oldest snapshot when keep-* values are not sati…
This commit is contained in:
Michael Eischer 2023-06-17 15:41:17 +02:00 committed by GitHub
commit 9cbc2502c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 2 deletions

View File

@ -0,0 +1,9 @@
Enhancement: Keep oldest snapshot when there are not enough snapshots
The `forget` command now additionally preserves the oldest snapshot if fewer
snapshots are kept than allowed by the `--keep-*` parameters. This maximizes
amount of history kept while the specified limits are not yet reached.
https://github.com/restic/restic/issues/3624
https://github.com/restic/restic/pull/4366
https://forum.restic.net/t/keeping-yearly-snapshots-policy-when-backup-began-during-the-year/4670/2

View File

@ -183,6 +183,7 @@ type KeepReason struct {
// according to the policy p. list is sorted in the process. reasons contains // according to the policy p. list is sorted in the process. reasons contains
// the reasons to keep each snapshot, it is in the same order as keep. // the reasons to keep each snapshot, it is in the same order as keep.
func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots, reasons []KeepReason) { func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots, reasons []KeepReason) {
// sort newest snapshots first
sort.Stable(list) sort.Stable(list)
if p.Empty() { if p.Empty() {
@ -256,7 +257,9 @@ func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots, reason
// -1 means "keep all" // -1 means "keep all"
if b.Count > 0 || b.Count == -1 { if b.Count > 0 || b.Count == -1 {
val := b.bucker(cur.Time, nr) val := b.bucker(cur.Time, nr)
if val != b.Last { // also keep the oldest snapshot if the bucket has some counts left. This maximizes the
// the history length kept while some counts are left.
if val != b.Last || nr == len(list)-1 {
debug.Log("keep %v %v, bucker %v, val %v\n", cur.Time, cur.id.Str(), i, val) debug.Log("keep %v %v, bucker %v, val %v\n", cur.Time, cur.id.Str(), i, val)
keepSnap = true keepSnap = true
buckets[i].Last = val buckets[i].Last = val
@ -275,7 +278,7 @@ func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots, reason
if cur.Time.After(t) { if cur.Time.After(t) {
val := b.bucker(cur.Time, nr) val := b.bucker(cur.Time, nr)
if val != b.Last { if val != b.Last || nr == len(list)-1 {
debug.Log("keep %v, time %v, ID %v, bucker %v, val %v %v\n", b.reason, cur.Time, cur.id.Str(), i, val, b.Last) debug.Log("keep %v, time %v, ID %v, bucker %v, val %v %v\n", b.reason, cur.Time, cur.id.Str(), i, val, b.Last)
keepSnap = true keepSnap = true
bucketsWithin[i].Last = val bucketsWithin[i].Last = val

View File

@ -14,6 +14,11 @@
"time": "2014-11-22T10:20:30Z", "time": "2014-11-22T10:20:30Z",
"tree": null, "tree": null,
"paths": null "paths": null
},
{
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
} }
], ],
"reasons": [ "reasons": [
@ -55,6 +60,19 @@
"counters": { "counters": {
"yearly": 7 "yearly": 7
} }
},
{
"snapshot": {
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
},
"matches": [
"yearly snapshot"
],
"counters": {
"yearly": 6
}
} }
] ]
} }

View File

@ -49,6 +49,11 @@
"time": "2014-11-22T10:20:30Z", "time": "2014-11-22T10:20:30Z",
"tree": null, "tree": null,
"paths": null "paths": null
},
{
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
} }
], ],
"reasons": [ "reasons": [
@ -201,6 +206,19 @@
"counters": { "counters": {
"yearly": 7 "yearly": 7
} }
},
{
"snapshot": {
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
},
"matches": [
"yearly snapshot"
],
"counters": {
"yearly": 6
}
} }
] ]
} }

View File

@ -44,6 +44,11 @@
"time": "2014-11-22T10:20:30Z", "time": "2014-11-22T10:20:30Z",
"tree": null, "tree": null,
"paths": null "paths": null
},
{
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
} }
], ],
"reasons": [ "reasons": [
@ -152,6 +157,17 @@
"yearly within 9999y" "yearly within 9999y"
], ],
"counters": {} "counters": {}
},
{
"snapshot": {
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
},
"matches": [
"yearly within 9999y"
],
"counters": {}
} }
] ]
} }

View File

@ -57,6 +57,11 @@
"time": "2014-08-22T10:20:30Z", "time": "2014-08-22T10:20:30Z",
"tree": null, "tree": null,
"paths": null "paths": null
},
{
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
} }
], ],
"reasons": [ "reasons": [
@ -189,6 +194,18 @@
"monthly snapshot" "monthly snapshot"
], ],
"counters": {"Monthly": -1, "Yearly": -1} "counters": {"Monthly": -1, "Yearly": -1}
},
{
"snapshot": {
"time": "2014-08-08T10:20:30Z",
"tree": null,
"paths": null
},
"matches": [
"monthly snapshot",
"yearly snapshot"
],
"counters": {"Monthly": -1, "Yearly": -1}
} }
] ]
} }