我正在寻找一个非常基本的备份脚本/包,用于备份我 Ubuntu 服务器上的目录。目前,我正在使用如下的 cronjob:
0 5 * * 1 sudo tar -Pzcf /var/backups/home.tgz /home/
但我想要一个解决方案,它可以在文件名中添加时间戳,并且不会覆盖旧备份。当然,这会慢慢淹没我的驱动器,因此需要自动删除旧备份(例如超过 2 个月的备份)。
干杯,丹尼斯
更新:我决定将赏金授予 -solution,logrotate
因为它很简单。但也非常感谢所有其他回答者!
答案1
使用 logrotate 的简单解决方案
如果您希望保持简单并且不编写脚本,只需保留当前的 cronjob 并为其配置 logrotate 规则。
为此,请将以下内容放入名为的文件中/etc/logrotate.d/backup-home
:
/var/backups/home.tgz {
weekly
rotate 8
nocompress
dateext
}
从现在开始,每次运行 logrotate(通常每天早上 6:25 左右运行),它都会检查是否适合轮换,如果适合,则将其重命名home.tgz
为另一个文件并添加时间戳。它会保留 8 个副本,因此您大约有两个月的历史记录。
您可以使用以下方式自定义时间戳日期格式选项,请参见logrotate(8)。
因为您的备份作业在凌晨 5 点运行,而 logrotate 在凌晨 6 点 25 分运行,所以您应该确保您的 tar 备份在 1 小时 25 分钟内运行良好(我想无论如何它会快得多)。
答案2
这是我使用的脚本(的变体)(/home/pduck/bup.sh
):
#!/usr/bin/env bash
src_dir=/home/pduck
tgt_dir=/tmp/my-backups
mkdir -p $tgt_dir
# current backup directory, e.g. "2017-04-29T13:04:50";
now=$(date +%FT%H:%M:%S)
# previous backup directory
prev=$(ls $tgt_dir | grep -e '^....-..-..T..:..:..$' | tail -1);
if [ -z "$prev" ]; then
# initial backup
rsync -av --delete $src_dir $tgt_dir/$now/
else
# incremental backup
rsync -av --delete --link-dest=$tgt_dir/$prev/ $src_dir $tgt_dir/$now/
fi
exit 0;
在我的例子中,它用于rsync
将文件从我的主目录本地复制到备份位置/tmp/my-backups
。在该目标目录下创建一个带有当前时间戳的目录,例如,/tmp/my-backups/2018-04-29T12:49:42
在该目录下放置当天的备份。
当脚本再次运行时,它会注意到已经有一个目录/tmp/my-backups/2018-04-29T12:49:42
(它会选择与时间戳模式匹配的“最新”目录)。然后它会执行命令,rsync
但这次使用--link-dest=/tmp/my-backups/2018-04-29T12:49:42/
开关指向上一个备份。
这是进行增量备份的实际要点:
使用--link-dest=…
rsync 不会复制与 link-dest 目录中的文件相比没有变化的文件。相反,它只会创建硬链接当前文件和先前文件之间。
当您运行此脚本 10 次时,您将获得 10 个具有不同时间戳的目录,每个目录都保存了当时文件的快照。您可以浏览目录并恢复所需的文件。
管理也非常简单:只需rm -rf
保留您不想保留的时间戳目录。这不会删除较旧、较新或未更改的文件,只会删除(减少)硬链接。例如,如果您有三代:
/tmp/my-backups/2018-04-29T...
/tmp/my-backups/2018-04-30T...
/tmp/my-backups/2018-05-01T...
并删除第二个目录,那么你就会丢失快照但文件仍然在第一个或第三个目录中(或两者)。
我放入了一个 cronjob,/etc/cron.daily
内容如下:
#!/bin/sh
/usr/bin/systemd-cat -t backupscript -p info /home/pduck/bup.sh
给这个文件命名backup
或者类似的东西chmod +x
,但是忽略后缀.sh
(此时不会运行)。由于/usr/bin/systemd-cat -t backupscript -p info
您可以通过 来查看进度journalctl -t backupscript
。
请注意,由于硬链接,此rsync
解决方案要求目标目录位于文件系统上。ext4
答案3
对 cron 命令进行一些编辑后,您就可以向文件名添加时间戳:
0 5 * * 1 sudo tar -Pzcf /var/backups/home_$(date "+%Y-%m-%d_%H-%M-%S").tgz /home/
至于清理,我发现了一个很棒的单行脚本这里我根据你的情况进行了调整:
find . -type f -name 'home_*.tgz' -exec sh -c 'bcp="${1%_*}"; bcp="${bcp#*_}"; [ "$bcp" "<" "$(date +%F -d "60 days ago")" ] && rm "$1"' 0 {} \;
您可以将上述命令添加到另一个 cron 作业中,它将删除超过 60 天的备份。HTH
答案4
以下是我的每日备份脚本(由 cron 调用)的部分解决方案:将 Linux 配置、脚本和文档备份到 Gmail。完整脚本不合适,因为:
- 它包含目标
/home/me/*
文件,但跳过了/home/
FireFox、Chrome 和其他应用程序使用的 1 GB 的重要文件,我对备份这些文件不感兴趣。 - 它包含对我来说很重要但对你来说不重要的文件
/etc/cron*
,,,,,,,等。/etc/system*
/lib/systemd/system-sleep
/etc/rc.local
/boot/grub
/usr/share/plymouth
/etc/apt/trusted.gpg
- 它每天早上都会将备份通过电子邮件发送到我的 gmail.com 帐户,以供异地备份。您的备份不仅在现场,而且在同一台机器上。
以下是相关脚本,您可以调整其中的部分内容:
#!/bin/sh
#
# NAME: daily-backup
# DESC: A .tar backup file is created, emailed and removed.
# DATE: Nov 25, 2017.
# CALL: WSL or Ubuntu calls from /etc/cron.daily/daily-backup
# PARM: No parameters but /etc/ssmtp/ssmtp.conf must be setup
# NOTE: Backup file name contains machine name + Distro
# Same script for user with multiple dual boot laptops
# Single machine should remove $HOSTNAME from name
# Single distribution should remove $Distro
sleep 30 # Wait 30 seconds after boot
# Running under WSL (Windows Subsystem for Ubuntu)?
if cat /proc/version | grep Microsoft; then
Distro="WSL"
else
Distro="Ubuntu"
fi
today=$( date +%Y-%m-%d-%A )
/mnt/e/bin/daily-backup.sh Daily-$(hostname)-$Distro-backup-$today
我的 gmail.com 只占用了 35%(总共 15 GB),因此我的每日备份可以运行一段时间,之后我才需要删除文件。但我不会采用“删除所有比 xxx 更早的文件”的理念,而是采用以下概述的祖父-父亲-儿子策略:我有必要保留备份记录吗?。 总之:
- 周一至周日(每日备份),14 天后清除
- 周日备份(每周备份)8 周后清除
- 每月最后一天的备份(每月备份)在 18 个月后清除
- 每年最后一天的备份(年度备份)永久保存
我的清除过程会变得复杂,因为我必须学习 Python 并安装一个 Python 库来管理 gmail 文件夹。
如果您不想要代际备份并想要清除超过 2 个月的文件,那么这个答案会有所帮助:通过 bash 脚本查找不删除文件夹中的文件。
总之:
DAYS_TO_KEEP=60
find $BACKUP_DIR -maxdepth 1 -mtime +"$DAYS_TO_KEEP" -exec rm -rf {} \;