我经常使用 Virtual Box 来测试发行版/应用程序。
我非常喜欢它的一个功能是虚拟机快照,它可以保存虚拟机的状态,并且如果出现问题,可以将其恢复到以前的状态,不会出现任何问题,也不会占用所有硬盘空间。
在我的实时系统上,我知道如何创建文件系统的 1:1 映像,但我所知道的所有解决方案都会创建完整文件系统的新映像。
是否有任何程序/文件系统能够对当前文件系统进行快照,将其保存在另一个位置,但不是创建全新的图像而是创建增量备份?
为了简单描述我想要的东西,它应该是dd
文件系统的图像,但它不仅仅是完整备份,还会创建增量备份。
我不需要 clonezilla 等。它应该在系统本身内运行,无需(或几乎无需)用户干预,但包含文件系统的所有数据。我也不想要备份duplicity
整个系统(不包括某些文件夹脚本)+dd
以保存您的 mbr。我可以自己做,寻找额外的技巧。
我正在寻找在对系统进行大规模更改之前可以做的事情,然后如果出现问题或者我在硬盘上洒了咖啡后烧毁了硬盘,我可以从 liveCD 启动并将工作快照恢复到硬盘。
不需要每天运行,甚至不需要制定时间表。只需偶尔运行并让它完成工作,最好是基于 RAW 而不是基于文件副本。
答案1
解释cprofitt 的回答(正如他的回答是增量,正如我将会解释的那样)......
首先您需要了解硬链接。
硬链接指向磁盘上实际存在的数据(物理位置),您可以使用硬链接访问数据。每个文件和目录都是指向物理磁盘上数据位置的硬链接。因此,如果有两个文件(硬链接)指向同一位置,则数据仅存储一次。
cprofitt 给出的流程包括:
轮换备份以腾出空间放置新备份。(昨天的“今日备份”变为“昨日备份”,两天前的“昨日备份”变为“两天前的备份”,以此类推)
- 只要您需要,列表就会不断增长,但在脚本中它只有 4 个快照。(它会为下一个级别(例如一周 - “本周的备份”)再次执行整个过程并轮换这些快照,所以这就是它只有 4 个的原因)。
- 移动是反向进行的,以防止覆盖
将您制作的最新快照(例如“昨天的备份”)复制到新快照的位置(例如“今天的备份”),在不复制文件的情况下为现有文件创建新的硬链接。因此,新快照中的所有文件都是指向与前一个相同的位置。
图示示例
在下图中,具有相同文件名且颜色相同的文件是指向磁盘上同一文件的硬链接。这里我们只处理两个快照和几个文件,但示例是可扩展的。(除了我在 cproffit 的答案中以与脚本相反的方式移动快照这一事实)
流程如下:
这是系统的一个快照。
快照是副本(创建到现有文件的硬链接)
运行 Rsync 来更新快照。当文件发生更改时,它会将新文件作为新副本存储在硬盘上(因此旧快照不会更改)。在此示例中,文件 B 已发生更改。笔记:我们现在硬盘上只存储了文件 A 和文件 C 的 1 个副本以及文件 B 的 2 个副本
旋转快照(在这种情况下,快照 0“脱落”并被删除,我将快照 1 重命名为快照 0)
再次复制快照(重复步骤 2)
再次 Rsync。(重复步骤 3)。现在我们有文件 A 的 1 个副本以及文件 B 和文件 C 的 2 个副本
[第一个]脚本的简化版本(不运行,仅作为垫脚石)如下:
#!/bin/bash
# Delete the snapshot we don't want (has 'fallen off')
rm -rf /root/snapshot/home/hourly.3 ;
# Rotate the snapshots by shuffling them back
mv /root/snapshot/home/hourly.2 /root/snapshot/home/hourly.3 ;
mv /root/snapshot/home/hourly.1 /root/snapshot/home/hourly.2 ;
# Copy the snapshot (creating hard links to the existing files)
cp -al /root/snapshot/home/hourly.0 /root/snapshot/home/hourly.1 ;
# Do the rsync ...
# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first. If it were not so, this would copy over the other
# snapshot(s) too!
rsync -va --delete /home/ /root/snapshot/home/hourly.0 ;
现在完整脚本有了完整的解释这里(正如 cprofitt 所链接的)它更详尽,但基本上与上述相同。另一个脚本用于对快照进行分组,cprofitt 的答案的另一部分讨论了使该过程自动化(使用 cron)并验证备份是否成功。
您可以更改名称,这样目录就不会被称为“hourly...”,而是被称为其他名称,并且脚本会手动运行。
要恢复所有内容,请将最新的快照(或之前的快照)复制回您备份的目录。
要恢复仍在快照中的单个文件,请转到快照并将其复制回其所属位置。
备份介质可以是外部硬盘(必须是 ext2/ext3/ext4)。如果您正在备份/
(主要是/boot
、/home
和/etc
/root
)/usr
,那么说...
您安装外部驱动器,执行备份并创建最新的快照。
卸载驱动器。
记住,您删除了一个您想要的文件(甚至是从垃圾箱中)。
连接外部驱动器并检索文件。
进行备份(以确保安全)
断开驱动器并开始旅行......
意识到笔记本电脑和熔岩不能混合。
使用运行 Live CD 的新笔记本电脑,格式化内部驱动器,安装外部驱动器,然后
cp -a /media/external/snapshot-0/* /media/internal-drive
(假设快照 0 是最新快照)将 grub 安装到 MBR(是的,它必须是单独的) - 或者用来
dd
备份 mbr,就像 cprofitt 在他的答案底部所说的那样。重启。
脚本需要改进(以便只获取您想要的内容),并且上述过程假设您没有分区。如果您有(或曾经有)分区,请在磁盘上创建一个新分区,并在复制之前/home
将其安装到位。mount /dev/sdxy /media/external/home
答案2
您可以使用 rsync。
Listing one: make_snapshot.sh
#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility
# ----------------------------------------------------------------------
# this needs to be a lot more general, but the basic idea is it makes
# rotating backup-snapshots of /home whenever called
# ----------------------------------------------------------------------
unset PATH # suggestion from H. Milz: avoid accidental use of $PATH
# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;
MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;
TOUCH=/bin/touch;
RSYNC=/usr/bin/rsync;
# ------------- file locations -----------------------------------------
MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;
EXCLUDES=/usr/local/etc/backup_exclude;
# ------------- the script itself --------------------------------------
# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi
# attempt to remount the RW mount point as RW; else abort
$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
exit;
}
fi;
# rotating snapshots of /home (fixme: this should be more general)
# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then \
$RM -rf $SNAPSHOT_RW/home/hourly.3 ; \
fi ;
# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/hourly.2 ] ; then \
$MV $SNAPSHOT_RW/home/hourly.2 $SNAPSHOT_RW/home/hourly.3 ; \
fi;
if [ -d $SNAPSHOT_RW/home/hourly.1 ] ; then \
$MV $SNAPSHOT_RW/home/hourly.1 $SNAPSHOT_RW/home/hourly.2 ; \
fi;
# step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if [ -d $SNAPSHOT_RW/home/hourly.0 ] ; then \
$CP -al $SNAPSHOT_RW/home/hourly.0 $SNAPSHOT_RW/home/hourly.1 ; \
fi;
# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first. If it were not so, this would copy over the other
# snapshot(s) too!
$RSYNC \
-va --delete --delete-excluded \
--exclude-from="$EXCLUDES" \
/home/ $SNAPSHOT_RW/home/hourly.0 ;
# step 5: update the mtime of hourly.0 to reflect the snapshot time
$TOUCH $SNAPSHOT_RW/home/hourly.0 ;
# and thats it for home.
# now remount the RW snapshot mountpoint as readonly
$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
exit;
} fi;
第二:
Listing two: daily_snapshot_rotate.sh
#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility: daily snapshots
# ----------------------------------------------------------------------
# intended to be run daily as a cron job when hourly.3 contains the
# midnight (or whenever you want) snapshot; say, 13:00 for 4-hour snapshots.
# ----------------------------------------------------------------------
unset PATH
# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;
MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;
# ------------- file locations -----------------------------------------
MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;
# ------------- the script itself --------------------------------------
# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi
# attempt to remount the RW mount point as RW; else abort
$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
exit;
}
fi;
# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/daily.2 ] ; then \
$RM -rf $SNAPSHOT_RW/home/daily.2 ; \
fi ;
# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/daily.1 ] ; then \
$MV $SNAPSHOT_RW/home/daily.1 $SNAPSHOT_RW/home/daily.2 ; \
fi;
if [ -d $SNAPSHOT_RW/home/daily.0 ] ; then \
$MV $SNAPSHOT_RW/home/daily.0 $SNAPSHOT_RW/home/daily.1; \
fi;
# step 3: make a hard-link-only (except for dirs) copy of
# hourly.3, assuming that exists, into daily.0
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then \
$CP -al $SNAPSHOT_RW/home/hourly.3 $SNAPSHOT_RW/home/daily.0 ; \
fi;
# note: do *not* update the mtime of daily.0; it will reflect
# when hourly.3 was made, which should be correct.
# now remount the RW snapshot mountpoint as readonly
$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
exit;
} fi;
根据您的需要创建脚本后,将其添加到 cron 作业中。
crontab -e
添加以下内容:
0 */4 * * * /usr/local/bin/make_snapshot.sh
0 13 * * * /usr/local/bin/daily_snapshot_rotate.sh
它们使 make_snapshot.sh 每四小时整点运行一次,并使 daily_snapshot_rotate.sh 每天 13:00(即下午 1:00)运行一次。
来源:http://www.mikerubel.org/computers/rsync_snapshots/
* * * * * command to be executed
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)
如果您希望它每小时运行一次,您可以为每个小时添加一个 cron 作业。
另一个可能的选择是使用 rsnapshot
安装 rsnapshot(可在软件中心找到)
配置 rsnapshot 并指定备份源目录
打开 /etc/rsnapshot.conf 并取消注释以下行。
# nano /etc/rsnapshot.conf
cmd_cp /bin/cp
cmd_ssh /usr/bin/ssh
cmd_du /usr/bin/du
cmd_rsnapshot_diff /usr/local/bin/rsnapshot-diff
logfile /var/log/rsnapshot
在 /etc/rsnapshot.conf 中定义目标备份目录,如下所示。在此示例中,
/home – 应备份的源目录 localhost/ – 将存储备份的目标目录。请注意,此目录将在 /.snapshots/{internal.n}/ 目录下创建,如上一步所示。
nano /etc/rsnapshot.conf
备份 /home/localhost/
测试 rsnapshot 配置
执行配置测试以确保 rsnapshot 正确设置并准备好执行 linux rsync 备份。
# rsnapshot configtest
Syntax OK
- 验证 rsnapshot 每小时备份配置
您可以按不同的时间间隔备份 Linux 目录或文件。默认情况下,配置每小时和每日备份。
验证每小时备份配置。
# rsnapshot -t hourly
echo 6490 > /var/run/rsnapshot.pid
mkdir -m 0700 -p /.snapshots/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded /home \
/.snapshots/hourly.0/localhost/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded /etc \
/.snapshots/hourly.0/localhost/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded \
/usr/local /.snapshots/hourly.0/localhost/
touch /.snapshots/hourly.0/
- 验证 rsnapshot 每日备份配置
验证每日 rsnapshot cwrsync 备份过程是否配置正确。
# rsnapshot -t daily
echo 6493 > /var/run/rsnapshot.pid
mkdir -m 0700 -p /.snapshots/
/.snapshots/hourly.5 not present (yet), nothing to copy
- 为 rsnapshot 添加 Crontab 条目
一旦您验证了 rsnapshot cwrsync 实用程序中 rsync 每小时和每日备份配置已正确设置,就该在 crontab 中设置这个小程序了,如下所示。
# crontab -e
0 */4 * * * /usr/local/bin/rsnapshot hourly
30 23 * * * /usr/local/bin/rsnapshot daily
来源:http://www.thegeekstuff.com/2009/08/tutorial-backup-linux-using-rsnapshot-rsync-utility/
---- 裸机恢复
我将使用 dd 和 tar 进行裸机恢复。
备份重要元数据:
# dd if-/dev/hda of=/backups/mbr bs=512 count=1
备份操作系统:
# mkdir /backups
# mount nfsserver:/backups/<servername> /backups
# cd /
# tar cfz /backups/system.tar.gz --exclude /mnt --exclude /proc --exclude /backups
如果我想制作裸机恢复文件,我个人倾向于让我的系统离线。
答案3
有两种方法可以进行基于块的增量备份
- 基于文件系统的快照
- 基于程序的快照
基于文件系统的快照
两个都虚拟文件系统和北卡罗莱纳州提供基于块的增量快照(北卡罗莱纳州,ZFS(第 25 页))。您可以拥有一个可以 rsync 到的驱动器,该驱动器可以是 ZFS 或 BTRFS,也可以是快照。
还有LVM 快照(cprofitt 提到)提供相同的基于块的增量快照。
基于程序的快照
有一个几个备份程序,但有几个目的却脱颖而出:
- 表里不一
- Rdiff 备份
我知道您特别提到您不是在寻找像 duplicity 这样的东西,但我想我可以提到一些功能。
但是这些程序需要您安装它们才能恢复。 rsync 之类的程序的优点在于几乎每个 Linux 安装都默认带有 rsync(例如,微型核心(10MB 发行版)缺少它)。
表里不一
它只存储差异(块级),然后压缩并加密它们。这比 rsync 方法占用的存储空间更小,但是(至少在我看来)文件系统需要重建,这将花费一些时间(如果您使用增量备份,则取决于自上次完整备份以来的时间)
这手册页解释其工作原理。
Rdiff 备份
客户端-服务器程序,像 duplicity 一样,创建块级差异,但它存储的是最新还原点的更改,因此最新快照的还原速度最快。回到过去(不是最新快照)需要分析更多差异,因此速度较慢。
有些人比较 rdiff-backup 与 rsnapshot(似乎是 rsync 方法的更自动化的方式)。几乎所有操作方法专注于通过网络使用 rdiff,但是我发现一个提到如何在本地主机上执行此操作。
答案4
我认为您可以使用 LVM 来实现这一点,但这仅仅是理论上的,而且会浪费大量硬盘。我的理论是,您可以让根系统驻留在逻辑卷上,然后如果您想进行测试,您可以创建快照并使用新卷重新启动机器。
LVM 快照需要原始卷才能工作。这是因为新卷保存了快照和真实文件系统之间的差异。
如果让系统处于这种状态,那么随着新文件系统的更改,您将开始浪费磁盘空间。我不知道是否有办法整合快照和最终文件系统。当然,您可以 dd 到另一个逻辑卷,但为此,您需要两倍的文件系统空间加上“恢复点”与当前状态之间的差异。
所有这些都需要重新启动,而且远非自动。
还假设几个现代文件系统都采用这种方式,例如 solaris 系统上的 zfs 或实验性的 btrfs。