backup-cronjob: rotation must not touch checkpoints/exports subdirs (use --delimiter / + strict regex)

This commit is contained in:
2026-04-28 10:58:54 +00:00
parent 760ee75877
commit 6168b86c2a

View File

@@ -149,15 +149,30 @@ spec:
echo "(filestore empty; skipping archive)"
fi
echo ">>> rotating: keep last $RETAIN snapshots under ${S3_PREFIX}/"
# Group keys by timestamp prefix (everything before
# the first dot after the date) and prune the oldest
# groups. Both .sql.gz and .filestore.tar.gz share
# the same timestamp prefix, so groups stay paired.
# Rotation must scope to the TOP-LEVEL dated backup
# files only — never touch checkpoints/, exports/,
# or blobs/ subdirectories. The previous version
# listed everything recursively under ${S3_PREFIX}/
# and grep'd for *.sql.gz, which matched
# checkpoints/<id>/db.sql.gz too — those sort
# ahead of the bare dated keys in reverse-alpha
# ('c' > '2'), so legitimate top-level backups
# routinely fell out of the keep-window AND
# checkpoint safety copies got deleted as a side
# effect. Use --delimiter / so list-objects-v2
# returns ONLY direct children of the prefix; the
# subdirectory keys come back as CommonPrefixes
# (which we discard).
#
# Both .sql.gz and .filestore.tar.gz share the
# same timestamp stem, so prune-by-stem keeps
# pairs aligned.
aws --endpoint-url "$S3_ENDPOINT" s3api list-objects-v2 \
--bucket "$S3_BUCKET" --prefix "${S3_PREFIX}/" \
--delimiter / \
--query 'Contents[].Key' --output text 2>/dev/null \
| tr '\t' '\n' \
| grep -E '\.sql\.gz$' \
| grep -E "^${S3_PREFIX}/[0-9]{8}T[0-9]{6}Z\.sql\.gz$" \
| sort -r | tail -n +$((RETAIN + 1)) \
| while read OLDSQL; do
[ -n "$OLDSQL" ] || continue