summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkapitainsky <dariuszb@me.com>2019-09-25 22:18:06 +0100
committerLaurent Cozic <laurent22@users.noreply.github.com>2019-09-25 22:18:06 +0100
commit48b42bf6ba95e4f2e49b8b2005f1036b2da0a5e8 (patch)
treea96b001d24dd51bebb84b590f1ff16f56850328e
parenteb5fe002e61f0d8d7f638d567b07bb4e29a99205 (diff)
Fix edge case in backup expiration logic (#166)
* bugfix - fn_expire_backups function * add BACKUP_TO_KEEP parameter * correct PREVIOUS_DEST test * variables case correction for consistency
-rwxr-xr-xrsync_tmbackup.sh58
1 files changed, 47 insertions, 11 deletions
diff --git a/rsync_tmbackup.sh b/rsync_tmbackup.sh
index 6fbf8f2..42dc3b5 100755
--- a/rsync_tmbackup.sh
+++ b/rsync_tmbackup.sh
@@ -96,8 +96,14 @@ fn_expire_backups() {
local current_timestamp=$EPOCH
local last_kept_timestamp=9999999999
- # Process each backup dir from most recent to oldest
- for backup_dir in $(fn_find_backups | sort -r); do
+ # we will keep requested backup
+ backup_to_keep="$1"
+ # we will also keep the oldest backup
+ oldest_backup_to_keep="$(fn_find_backups | sort | sed -n '1p')"
+
+ # Process each backup dir from the oldest to the most recent
+ for backup_dir in $(fn_find_backups | sort); do
+
local backup_date=$(basename "$backup_dir")
local backup_timestamp=$(fn_parse_date "$backup_date")
@@ -107,36 +113,60 @@ fn_expire_backups() {
continue
fi
+ if [ "$backup_dir" == "$backup_to_keep" ]; then
+ # this is the latest backup requsted to be kept. We can finish pruning
+ break
+ fi
+
+ if [ "$backup_dir" == "$oldest_backup_to_keep" ]; then
+ # We dont't want to delete the oldest backup. It becomes first "last kept" backup
+ last_kept_timestamp=$backup_timestamp
+ # As we keep it we can skip processing it and go to the next oldest one in the loop
+ continue
+ fi
+
# Find which strategy token applies to this particular backup
for strategy_token in $(echo $EXPIRATION_STRATEGY | tr " " "\n" | sort -r -n); do
IFS=':' read -r -a t <<< "$strategy_token"
- # After which date (relative to today) this token applies (X)
+ # After which date (relative to today) this token applies (X) - we use seconds to get exact cut off time
local cut_off_timestamp=$((current_timestamp - ${t[0]} * 86400))
- # Every how many days should a backup be kept past the cut off date (Y)
- local cut_off_interval=$((${t[1]} * 86400))
+ # Every how many days should a backup be kept past the cut off date (Y) - we use days (not seconds)
+ local cut_off_interval_days=$((${t[1]}))
# If we've found the strategy token that applies to this backup
if [ "$backup_timestamp" -le "$cut_off_timestamp" ]; then
# Special case: if Y is "0" we delete every time
- if [ $cut_off_interval -eq "0" ]; then
+ if [ $cut_off_interval_days -eq "0" ]; then
fn_expire_backup "$backup_dir"
break
fi
+ # we calculate days number since last kept backup
+ local last_kept_timestamp_days=$((last_kept_timestamp / 86400))
+ local backup_timestamp_days=$((backup_timestamp / 86400))
+ local interval_since_last_kept_days=$((backup_timestamp_days - last_kept_timestamp_days))
+
# Check if the current backup is in the interval between
# the last backup that was kept and Y
- local interval_since_last_kept=$((last_kept_timestamp - backup_timestamp))
- if [ "$interval_since_last_kept" -lt "$cut_off_interval" ]; then
+ # to determine what to keep/delete we use days difference
+ if [ "$interval_since_last_kept_days" -lt "$cut_off_interval_days" ]; then
+
# Yes: Delete that one
fn_expire_backup "$backup_dir"
+ # backup deleted no point to check shorter timespan strategies - go to the next backup
+ break
+
else
- # No: Keep it
+
+ # No: Keep it.
+ # this is now the last kept backup
last_kept_timestamp=$backup_timestamp
+ # and go to the next backup
+ break
fi
- break
fi
done
done
@@ -450,7 +480,13 @@ while : ; do
# Purge certain old backups before beginning new backup.
# -----------------------------------------------------------------------------
- fn_expire_backups
+ if [ -n "$PREVIOUS_DEST" ]; then
+ # regardless of expiry strategy keep backup used for --link-dest
+ fn_expire_backups "$PREVIOUS_DEST"
+ else
+ # keep latest backup
+ fn_expire_backups "$DEST"
+ fi
# -----------------------------------------------------------------------------
# Start backup