我正在尝试编写一个非常简单的备份策略。以下是总体思路。
每日 - 使用 rsync 备份整个文件系统,覆盖前一天备份。
每周 — 每周一次将每日备份复制到单独的文件夹保存一周,覆盖前一周的备份。
每月 - 每月第一天将每日备份复制到每月备份文件夹以保存一个月,覆盖上个月的备份。
难题就在这里:我每天都进行每周备份,每周和每日备份将是相同的,所以我不会有几天前的备份。
如果这一天恰逢每月的第一天,那么所有的备份都将相同,这样就降低了进行多次备份的意义。
我的空间有限,只能备份三个。我正在备份虚拟机和网站,所以不需要长期备份,但我确实需要可以追溯到一段时间的备份,以防错误在几天内被忽视。
有人有想法重新制定这个策略吗?所以我没有所有备份都相同的时期。
答案1
我会编写一个脚本来检查备份是否已超过 1、7 或 30 天,并采取相应措施。你没有这么说,但我假设你使用的是 Linux(我添加了Linux的标签到您的问题),并且您正在备份到远程服务器。第一步是编写一个小脚本,运行您的rsync
命令,并在备份完成后在远程服务器上创建一个文件。这将用于判断备份是否正在运行以及检查备份的年龄(我假设您在备份文件时保留原始时间戳,因此您无法从文件本身获取日期):
Rsync 脚本(假设您可以无需密码访问远程服务器):
#!/usr/bin/env bash
ssh user@remote rm /path/to/daily/backup/backup_finished.txt
rsync /path/to/source/ user@remote:/path/to/daily/backup/
ssh user@remote touch /path/to/daily/backup/backup_finished.txt
在当地的机器,设置一个计划任务进行每日备份:
@daily rsync_script.sh
在偏僻的机器,你需要每隔几个小时运行我下面提供的脚本:
@hourly check_backup.sh
check_backup.sh脚本:
#!/usr/bin/env bash
daily=/path/to/daily;
weekly=/path/to/weekly;
monthly=/path/to/monthly;
## The dates will be measured in seconds since the UNIX epoch,
## so we need to translate weeks and months (31 days) to seconds.
week=$((60*60*24*7));
month=$((60*60*24*31));
## Make sure no backup is currently running
if [ ! -e $daily/backup_finished.txt ]; then
echo "A backup seems to be running, exiting." && exit;
fi
## Get the necessary dates
weekly_backup_date=$(stat -c %Y $weekly/backup_finished.txt)
monthly_backup_date=$(stat -c %Y $monthly/backup_finished.txt)
now=$(date +%s)
monthly_backup_age=$((now - monthly_backup_date))
weekly_backup_age=$((now - weekly_backup_date))
## Check the age of the daily backup and copy it accordingly
if [[ "$monthly_backup_age" -gt "$month" ]]; then
## Copy unless the current $daily is identical to $weekly
diff $daily $weekly > /dev/null ||
## Delete the previous backup and copy the new one over
rm -rf $monthly && cp -rp $daily $monthly
fi
## Copy the weekly backup if it is older than a week but only
## if it is not identical to $monthly. The -r flag makes cp
## recursive and the -p flag makes it preserve dates and permissions.
if [[ "$weekly_backup_age" -gt "$week" ]]; then
## Copy unless the current $daily is identical to $monthly
diff $daily $monthly > /dev/null ||
rm -rf $weekly && cp -rp $daily $weekly
fi
因此,此脚本 ( check_backup.sh
) 将每小时在您的备份服务器上运行一次。除非备份足够旧,否则它不会执行任何操作,因此让它如此频繁地运行是没有问题的。现在,每次每日备份超过 31 天时,它都会被复制到目录中monthly
,并且内容monthly
将被删除。当备份超过 7 天时,每周备份也是如此。
我用它diff
来比较备份。这意味着如果当前备份超过一周,我们将复制daily
到weekly
weekly
但只有如果要复制的备份(当前daily
)与现有的 不同weekly
,则类似monthly
。例如,如果脚本刚刚运行,并且发现每月备份与当前每周备份相同,则它不会覆盖现有的monthly
。但是,一周后,当weekly
发生变化时,它将复制一个monthly
。
这样做的最终结果是,无论何时,您都应至少拥有两个不同的备份,通常您会拥有三个。最糟糕的情况是,出现故障,而您没有一周前的备份,只有一个月前的备份,或者,反之亦然,您没有一个月前的,但是您有上周的。
答案2
这更像是一条长评论,补充了其他人已经指出的内容。
首先,使用硬链接和增量备份与 rsync 可以大大减少实际使用的磁盘空间量:每个额外的备份只会占用不同文件的大小。如果您要备份大型 VM 映像,那么我建议不要备份映像文件,而是备份它们的文件系统内容(正如 @Michael 已经评论的那样)。像 rsnapshot 这样的工具应该可以正常工作,尽管(根据经验)编写自己的脚本很容易。
然后删除旧备份,并逐渐延长保留时间。我曾经编写了一个程序来专门配置这一点,可以找到这里(称为bu-rmselect
)。
答案3
我是命令行程序的作者时间间隔,它允许您过滤定期创建的备份并拒绝(列出、删除或移动)较旧的备份,以便随着备份年限的增加,接受的备份之间的“时间差距”变得更大。
考虑以下情况:*.tar.gz
当前工作目录中的所有文件恰好是某事物的每日快照。现在的任务是接受过去 20 天每天的一个快照、过去 8 周每天的一个快照以及过去 12 个月每天的一个快照,并移动所有其他人到目录notneededanymore
。使用时间间隔,这是一项简单的任务:
$ mkdir notneededanymore
$ timegaps --move notneededanymore days20,weeks8,months12 *.tar.gz