Files
sqlite-backup-s3/scripts/deleteold.sh
T
vasyansk 3183bf5267
docker-build / Build image (push) Successful in 25s
Add KEEP_LAST retention policy for backups
Add KEEP_LAST environment variable to always preserve the N most recent
backups regardless of age, preventing data loss when backups haven't
been created for extended periods. Defaults to 10 copies.
2026-09-01 12:09:19 +07:00

53 lines
1.6 KiB
Bash
Executable File

#!/bin/bash
set -u
# Retention: delete backups older than DELETE_AFTER days, but always keep
# at least KEEP_LAST most recent copies regardless of their age.
DATE_NOW=$(date +%s)
DEST="${MINIO_PATH%/}/"
KEEP_LAST="${KEEP_LAST:-10}"
case "$KEEP_LAST" in
''|*[!0-9]*) echo "WARN: KEEP_LAST is not a number ('$KEEP_LAST'), falling back to 10"; KEEP_LAST=10 ;;
esac
LIST=$(mktemp)
trap 'rm -f "$LIST"' EXIT
# `rclone ls` prints "<size> <path>". Filenames are sqlite_<YYYY-MM-DD-HHMMSS>.tar.gz,
# so a reverse lexicographic sort is a reverse chronological sort.
/scripts/minio_uploader.sh list "$DEST" \
| awk '{ print $2 }' \
| grep "^sqlite_" \
| sort -r > "$LIST"
TOTAL=$(wc -l < "$LIST" | tr -d ' ')
echo "Found $TOTAL backups, keeping at least $KEEP_LAST most recent, max age $DELETE_AFTER days"
if [ "$TOTAL" -le "$KEEP_LAST" ]; then
echo "Nothing to rotate: $TOTAL backups <= KEEP_LAST=$KEEP_LAST"
exit 0
fi
# Only the tail beyond the protected window is a candidate for deletion.
tail -n "+$((KEEP_LAST + 1))" "$LIST" | while read -r BACKUP_FILENAME
do
[ -n "$BACKUP_FILENAME" ] || continue
BACKUP_DATE=$(echo "$BACKUP_FILENAME" | awk 'BEGIN { FS = "[_-]" } ; { printf "%s-%s-%s",$2,$3,$4 }')
if [[ $BACKUP_DATE =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
then
BACKUP_DATE_SECS=$(date -d "$BACKUP_DATE" +%s)
DAYS_DIFF=$(( (DATE_NOW - BACKUP_DATE_SECS) / (60*60*24) ))
if [ "$DAYS_DIFF" -gt "$DELETE_AFTER" ]
then
echo "File $BACKUP_FILENAME is $DAYS_DIFF days old (greater than $DELETE_AFTER days). Deleting it."
/scripts/minio_uploader.sh delete "${DEST}${BACKUP_FILENAME}"
fi
fi
done