我正在尝试创建一个 Bash 脚本来自动管理我的 AWS S3 存储桶中的备份。目标是保留最近一个月的所有备份,对于 30 天以上的备份,仅保留每周的最新备份。然而,我在准确识别每周的最新备份方面面临着挑战。下面是我的代码
#!/bin/bash
#set -x
R2_BUCKET="bucket name"
ENDPOINT_URL="https://key.r2.cloudflarestorage.com"
today=$(date +%s)
cutoff_date=$(date +%s -d "30 days ago")
declare -A weekly_latest_files
aws s3api list-objects --endpoint-url "$ENDPOINT_URL" --bucket "$R2_BUCKET" | jq -r '.Contents[] | "\(.Key) \(.LastModified)"' | while read file_key file_modified; do
file_modified_timestamp=$(date -d "$file_modified" +%s)
# Check if the file is within the last 30 days
if [[ $file_modified_timestamp -gt $cutoff_date ]]; then
echo "Keeping recent backup: $file_key"
else
# Get the ISO 8601 week number and year for the file's last modified date
year_week=$(date -d "$file_modified" +%Y-%U)
# Check if we have already stored the latest file for this week
if [[ -z "${weekly_latest_files[$year_week]}" || ${weekly_latest_files[$year_week]} -lt $file_modified_timestamp ]]; then
# If no file has been kept for this week, or the current file is newer than the stored one, update it
weekly_latest_files[$year_week]=$file_modified_timestamp
echo "Keeping latest backup for week of $file_modified: $file_key"
else
echo "Deleting old backup: $file_key"
# Uncomment to enable deletion (test thoroughly before uncommenting)
# aws s3api delete-object --endpoint-url "$ENDPOINT_URL" --bucket "$R2_BUCKET" --key "$file_key"
fi
fi
done
我尝试了多种方法,包括使用从文件名中提取的周数以及根据文件修改时间计算周开始时间戳。然而,这些方法要么保留了太多备份,要么删除了错误的备份。
我的代码有一个问题:当文件超过 30 天时,它每周保留两个文件(例如,周五和周六)。
AWS 针对这种情况有一个解决方案,那就是 S3 存储桶版本控制和生命周期策略。当您启用版本控制时,您可以将每个备份放入同一天的存储桶中。然后保留当前版本并在 30 天后删除非当前版本。这将确保您始终拥有至少一份副本,并且不会存储超出需要的副本。 https://docs.aws.amazon.com/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html
虽然您的解决方案可能有效,但它需要定期存储桶扫描和额外的基础设施来运行脚本。您可以完全跳过这一点并获得可靠的备份解决方案。