Discussion:
[BackupPC-devel] FullKeepCnt confusion
Eliyahu Neiman
2014-09-05 18:12:54 UTC
Permalink
I've been using BackupPC for a year or so, and I was surprised to find that
my oldest backup was not as old as I expected. This was because I had
FullKeepCnt set to : [4, 0, 2, 1, 0, 1]. I had assumed that this would lead
to one (full) backup at 52 weeks:

4 x 1 week | 4 weeks
2 x 4 weeks | 8 weeks
1 x 8 weeks | 8 weeks
1 x 32 weeks | 32 weeks
for a total of 52 weeks. Of course, what actually happens is that

1) the most recent backup is at week 0, not 1, so the oldest backup is at
51 weeks
2) more importantly, after 52 backups, kept backups are:
0, 32, 40, 44, 48, 49, 50, 51
but after 53 backups, kept backups are:
32, 40, 44, 48, 49, 50, 51, 52
with the oldest being only 20 weeks, not anywhere near 52.

I think that this is largely due to the confusing nature of the way
FullKeepCnt works. I would like to suggest the following for a future
version:

A new setting, $Conf{FullKeepCycles} (or possibly a reimagined
$Conf{FullPeriod}), to function as follows:

$Conf{FullKeepCycles} = [7, 30, 180, 365]
would mean:
keep full backups at 7 days until 30 days,
then keep backups at 30 days until 180 days,
then keep backups at 180 days until 365 days,
then keep 1 backup at 365 days.

--------------------------------

Practically speaking, how would this work?

Define the minimum age of a Cycle-n backup to be A_n:
$Conf{FullKeepCycles} = [A_0, A_1, A_2, A_3, ... ]

Define the time period between Cycle-n backups to be P_n.
P_0 = A_0
If we require that Cycle-n backups must never be less frequent than A_n
(i.e. P_n <= A_n), that period, P_n, will be the nearest multiple of
P_(n-1) that is less than or equal to A_n.

In our case,

Cycle 0: P_0 = 7
Cycle 1: P_1 = 28
Cycle 2: P_2 = 168
Cycle 3: P_3 = 336

(For Cycle-n_max, however, P_n is irrelevant, since only 1 backup is kept.)

Now, on to our example:

First, Cycle-0 backups are kept at P_0 = A_0 = 7 days:
7-day: 0, 1, 2, 3, 4 (The oldest here is 28 days)

When a backup crosses the A_1 = 30-day boundary, it is kept as a Cycle-1
Backup:
30-day: 0,
7-day: 1, 2, 3, 4, 5

The next time a backup crosses the A_1 boundary, it is deleted, until the
newest Cycle-1 Backup (in this case, #0) becomes more than P_1 days "old"
in its Cycle-1 status. This means it is at least A_1 + P_1 = 30 + 24 = 54
days old.
30-day: 0, 4,
7-day: 5, 6, 7, 8, 9

Again, backups crossing the A_1 boundary are deleted until the next Cycle-1
backup (#4) crosses the 54-day boundary:
30-day: 0, 4, 8,
7-day: 9, 10, 11, 12, 13

This continues until a Cycle-1 backup crosses the A_2 = 180-day boundary,
at which point it becomes a Cycle-2 backup:
180-day: 0,
30-day: 4, 8, 12, 16, 20,
7-day: 22, 23, 24, 25, 26

Again, backups crossing the A_2 boundary are deleted until a Cycle-2 backup
(#0) crosses the A_2 + P_2 = 348-day boundary:
180-day: 0, 24,
30-day: 28, 32, 36, 40. 44
7-day: 46, 47, 48, 49, 50

Eventually, #0 crosses the A_3 = 365-day boundary and enters its final
state, a Cycle-3 backup:
365-day: 0,
180-day: 24,
30-day: 28, 32, 36, 40, 44,
7-day: 48, 49, 50, 51, 52

After that, #0 will stick around until the next time a backup crosses the
A_3 boundary, at which point it is finally deleted:
365-day: 24,
180-day: 48,
30-day: 52, 56, 60, 64, 68, 72,
7-day: 73, 74, 75, 76, 77

This would ensure that backups are always at least as old as the cycle age
as given by the user. Also, the user will not need to do any complicated
calculations to determine the desired settings for FullKeepCnt, since
FullKeepCycles presents a much more intuitive user experience.

Elliott

Loading...