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.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
DB_FILE=/data/db.sqlite
|
DB_FILE=/data/db.sqlite
|
||||||
CRONTAB="00 06 * * *"
|
CRONTAB="00 06 * * *"
|
||||||
DELETE_AFTER=10
|
DELETE_AFTER=10
|
||||||
|
KEEP_LAST=10
|
||||||
TZ=Asia/Novosibirsk
|
TZ=Asia/Novosibirsk
|
||||||
MINIO_PATH=myminio://sqlite/master/
|
MINIO_PATH=myminio://sqlite/master/
|
||||||
MINIO_ACCOUNT_ID=account
|
MINIO_ACCOUNT_ID=account
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ services:
|
|||||||
- DB_FILE
|
- DB_FILE
|
||||||
- CRONTAB
|
- CRONTAB
|
||||||
- DELETE_AFTER
|
- DELETE_AFTER
|
||||||
|
- KEEP_LAST
|
||||||
- TZ
|
- TZ
|
||||||
- MINIO_PATH
|
- MINIO_PATH
|
||||||
- MINIO_ACCOUNT_ID
|
- MINIO_ACCOUNT_ID
|
||||||
@@ -28,6 +29,7 @@ services:
|
|||||||
DB_FILE=/data/db.sqlite
|
DB_FILE=/data/db.sqlite
|
||||||
CRONTAB="00 06 * * *"
|
CRONTAB="00 06 * * *"
|
||||||
DELETE_AFTER=10
|
DELETE_AFTER=10
|
||||||
|
KEEP_LAST=10
|
||||||
TZ=Asia/Novosibirsk
|
TZ=Asia/Novosibirsk
|
||||||
MINIO_PATH=myminio://sqlite/master/
|
MINIO_PATH=myminio://sqlite/master/
|
||||||
MINIO_ACCOUNT_ID=account
|
MINIO_ACCOUNT_ID=account
|
||||||
@@ -43,6 +45,18 @@ HEALTHCHECK_UUID=00000000-0000-0000-0000-000000000000
|
|||||||
1. myminio - системно! не менять
|
1. myminio - системно! не менять
|
||||||
2. проверьте настройки локации, не должно быть пусто
|
2. проверьте настройки локации, не должно быть пусто
|
||||||
3. DELETE_AFTER - в днях
|
3. DELETE_AFTER - в днях
|
||||||
|
4. KEEP_LAST - минимальное число копий, которые сохраняются всегда
|
||||||
|
|
||||||
|
## Ротация
|
||||||
|
|
||||||
|
Удаление старых бекапов работает по двум условиям одновременно:
|
||||||
|
|
||||||
|
1. бекап старше `DELETE_AFTER` дней
|
||||||
|
2. и при этом не входит в `KEEP_LAST` самых свежих копий
|
||||||
|
|
||||||
|
То есть последние `KEEP_LAST` бекапов не удаляются никогда, даже если они старше `DELETE_AFTER` дней. Это защищает от потери всех копий, если контейнер долго стоял и новые бекапы не создавались.
|
||||||
|
|
||||||
|
`KEEP_LAST` по умолчанию `10`, если переменная не задана.
|
||||||
|
|
||||||
## Healthchecks
|
## Healthchecks
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ services:
|
|||||||
- DB_FILE
|
- DB_FILE
|
||||||
- CRONTAB
|
- CRONTAB
|
||||||
- DELETE_AFTER
|
- DELETE_AFTER
|
||||||
|
- KEEP_LAST
|
||||||
- TZ
|
- TZ
|
||||||
- MINIO_PATH
|
- MINIO_PATH
|
||||||
- MINIO_ACCOUNT_ID
|
- MINIO_ACCOUNT_ID
|
||||||
|
|||||||
Regular → Executable
+28
-4
@@ -2,14 +2,38 @@
|
|||||||
|
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
# Seconds since epoch for current time
|
# 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)
|
DATE_NOW=$(date +%s)
|
||||||
DEST="${MINIO_PATH%/}/"
|
DEST="${MINIO_PATH%/}/"
|
||||||
|
KEEP_LAST="${KEEP_LAST:-10}"
|
||||||
|
|
||||||
/scripts/minio_uploader.sh list "$DEST" | grep "sqlite_" | while read -r LINE
|
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
|
do
|
||||||
# `rclone ls` prints "<size> <path>"
|
[ -n "$BACKUP_FILENAME" ] || continue
|
||||||
BACKUP_FILENAME=$(echo "$LINE" | awk '{ print $2 }')
|
|
||||||
|
|
||||||
BACKUP_DATE=$(echo "$BACKUP_FILENAME" | awk 'BEGIN { FS = "[_-]" } ; { printf "%s-%s-%s",$2,$3,$4 }')
|
BACKUP_DATE=$(echo "$BACKUP_FILENAME" | awk 'BEGIN { FS = "[_-]" } ; { printf "%s-%s-%s",$2,$3,$4 }')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user