如何制作和还原硬盘增量快照


13

我经常使用Virtual Box进行发行版/应用程序测试。

我最喜欢的功能之一是虚拟机快照,它可以保存虚拟机的状态,并能够将其恢复到以前的荣耀,如果您确实出错了,也没有任何问题,也不会占用所有硬盘空间。

在我的实时系统上,我知道如何创建文件系统的1:1映像,但是我所知道的所有解决方案都将创建完整文件系统的新映像。

是否有任何程序/文件系统能够拍摄当前文件系统的快照,然后将其保存在另一个位置,但是它不会创建一个完整的新映像,而是创建增量备份?

为了方便地描述我想要的内容,它应该作为dd文件系统的映像,但是它不仅会创建完整的备份,还会创建增量文件。


我不是在寻找clonezilla等。它应该在系统本身内运行,而无需用户干预(或几乎没有干预),但应包含文件系统的所有数据。我也不希望duplicity备份所有系统(不包括某些文件夹脚本+)dd来保存您的mbr。我可以自己做,寻找额外的技巧。

我正在寻找在对系统进行大规模更改之前可以做的事情,然后,如果出现错误或在洒了咖啡后烧毁了硬盘,我可以从liveCD引导并将工作快照恢复到硬盘上。

它不需要是每天,甚至不需要时间表。只是偶尔运行一次,使其工作,最好是基于RAW而不是基于文件复制。



因此,您正在寻找可以创建可安装映像的应用程序吗?如果不是,您为什么不喜欢Deja Dup?如果您要求应用程序可以创建可安装的映像,我也想知道该答案。添加收藏夹。
heartmagic 2011年

刚刚发布了标题为...的问题的答案...,但我看到您正在寻找更多的潜在方法来还原系统裸机,而不是在文件级别上。
cprofitt

1
听起来您想要基于块级别而不是文件系统的增量备份。除了使用支持快照的文件系统之外,我不确定您要的内容是否可行。LVM,BTRFS是可能的。
cprofitt

@cprofitt thx用于修复标题,它更正确。
布鲁诺·佩雷拉

@Bruno-制作好标题可以帮助以后来寻找答案的人们使用它。
cprofitt 2011年

Answers:


14

解释cprofitt的答案(因为他的答案渐进式的,我将解释)...

首先,您需要了解硬链接。

硬链接指向磁盘上实际存在的数据(物理位置),您可以使用硬链接访问数据。每个文件和目录都是到物理磁盘上数据位置的硬链接。因此,如果有两个指向相同位置的文件(硬链接),则数据仅存储一次


cprofitt给出的过程涉及:

  1. 旋转备份以创建一个新位置。(从昨天开始的“今天的备份”变为“昨天的备份”,从两天前的“昨天的备份”变为“两天前的备份”,依此类推)

    • 列表会根据您的需要不断增长,但是在脚本中只有4个快照。(它将为下一级别再次执行整个过程(例如,一周-“本周的备份”)并轮换这些,因此,它只有4个)。
    • 反向移动以防止覆盖
  2. 将您已完成的最新快照(例如“昨天的备份”)复制到新快照的位置(例如“今天的备份”),从而在不复制文件的情况下建立到现有文件的新硬链接。因此,新快照中的所有文件都指向与上一个相同的位置


图解的例子

在下图中,具有相同文件名的相同颜色的文件是指向磁盘上同一文件的硬链接。在这里,我们仅处理两个快照和一些文件,但是示例可以扩展。(除了我将快照移动到与cproffit答案中的脚本相反的事实之外)

在此处输入图片说明

过程是这样的:

  1. 有系统快照。

  2. 快照是副本(创建到现有文件的硬链接)

  3. 运行Rsync以更新快照。更改文件后,它将新文件作为新副本存储在硬盘上(因此不会更改旧快照)。在此示例中,文件B已更改。注意:我们现在只有1个文件A和文件C的副本以及两个文件B的副本存储在硬盘上

  4. 旋转快照(在这种情况下,快照0“掉落”并被删除,我将快照1重命名为快照0)

  5. 复制快照(重复步骤2)

  6. 再次进行Rsync。(重复步骤3)。现在我们有文件A的1个副本以及文件B和C的2个副本


这是[first]脚本的简化版本(不要作为垫脚石运行):

#!/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)并验证备份是否成功。

您可以更改名称,因此不必将目录称为“每小时...”,而是将其称为其他名称,并手动运行脚本。


要还原全部快照,请将最新快照(或上一个快照)复制回要备份的目录中。

要还原仍在快照中的单个文件,请转到快照并将其复制回它所属的位置。

备份媒体可以是外部硬盘驱动器(必须为ext2 / ext3 / ext4)。如果你备份/(主要是/boot/home/etc /root/usr)然后,说...

  1. 您安装外部驱动器,执行备份并创建最新快照。

  2. 卸下驱动器。

  3. 请记住,您删除了想要的文件(甚至从垃圾箱中删除)。

  4. 连接外部驱动器并检索文件。

  5. 进行备份(请确保)

  6. 断开驱动器并继续旅行...

  7. 意识到笔记本电脑和熔岩不会混在一起。

  8. 在新笔记本电脑运行实时cd的情况下,格式化内部驱动器,挂载外部驱动器,然后cp -a /media/external/snapshot-0/* /media/internal-drive(假设快照0是最新的快照)

  9. 将grub安装到MBR(是的,必须单独安装)-或用于dd备份mbr,如cprofitt在其回答的底部所说。

  10. 重启。

需要完善脚本(仅获取所需的内容),并且以上过程假定您没有/home分区。如果您已经(或曾经)在磁盘上创建了一个新磁盘,并mount /dev/sdxy /media/external/home在复制之前将其安装到位。


100个dd快照将100 x <average size of snapshot> 占用磁盘空间。其中100个将会花费<size of snapshot> + <size of changed files>。我用它把/ home(〜400GB)的几个快照放到500GB磁盘上。
Portablejim

您可以在文件系统上挂载虚拟磁盘映像,然后对其进行备份。参见superuser.com/questions/158908/…和链接
Portablejim,

就像说的那样,这是针对我正在运行的计算机,而不是虚拟盒子,vbox只是一个示例。
布鲁诺·佩雷拉

更新了问题(最后没有添加评论)。
Portablejim

@Portablejim:您正在编写cp是“保留硬链接”。我认为这句话令人困惑。cp -al正在建立到源文件的硬链接,而不是复制源文件。您的数字还应该反映出这一点,例如,通过显示图2中的A文件是同一文件。
丹尼尔·库尔曼2011年

7

您可以使用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

  1. 安装rsnapshot(在软件中心中提供)

  2. 配置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
  1. 如下所示,在/etc/rsnapshot.conf中定义目标备份目录。在这个例子中

    / home –应该备份的源目录localhost / –将存储备份的目标目录。请注意,该目录将在/.snapshots/{internal.n}/目录下创建,如最后一步所示。

    纳米/etc/rsnapshot.conf

    备份/ home /本地主机/

  2. 测试rsnapshot配置

执行配置测试,以确保rsnapshot正确设置并准备执行linux rsync备份。

# rsnapshot configtest
Syntax OK
  1. 验证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/
  1. 验证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
  1. 为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

如果我要制作裸机还原文件,我个人倾向于使系统脱机。


2
您的所有答案看起来都很好,没有任何问题,但不是我要问的,所有方法都无法还原MBR,dd并且不是增量方法。这些都不是我要问的。最后10%可能很有趣,但是其余所有信息转储实际上并不是。
布鲁诺·佩雷拉

上面的细节处理文件系统(作为文件系统),我添加了dd进程来处理MBR。
cprofitt

3

有两种方法可以执行基于块的增量备份

  • 基于文件系统的快照
  • 基于程序的快照

基于文件系统的快照

ZFSBTRFS提供基于增量快照块(BTRFSZFS(25页))。您可以将要同步的驱动器是ZFS或BTRFS和快照。

还有LVM快照(由cprofitt提及)提供相同的基于块的增量快照。

基于程序的快照

几个备份程序,但为此目的,有一些备份程序

我知道您特别提到过,您并不是要寻找重复性,但是我想我可能会提到一些功能。

但是,这些程序需要您安装它们才能还原。rsync之类的东西的优点在于,默认情况下,几乎每个Linux安装都具有rsync(例如,缺少内核(10MB发行版))。

表里不一

它只存储差异(块级别),然后对其进行压缩和加密。与rsync方法相比,这将导致更少的存储,但是(至少从我的角度来看)文件系统将需要重建,这将花费一些时间(如果您使用增量备份,并且这取决于从那时起的时间)。上次完整备份)

手册页解释了它是如何工作的。

Rdiff备份

客户端服务器程序会像重复一样创建块级差异,但是会存储最新还原点的更改,因此最新快照是还原最快的。时光倒流(不是最新快照)需要分析更多差异,因此速度较慢。

有些人将rdiff-backup与rsnapshot进行了比较(似乎是rsync mentod的一种更自动的方式)。几乎所有的入门指南重点介绍如何使用rdiff进行在网络上,但是我发现一个,其中提到如何做到这一点在本地主机上


好吧,我喜欢这样,关心描述如何使它与分区还原一起工作?即,如果我破坏了磁盘,我将如何从快照中还原整个系统,而不必自己创建分区,等等。不是很详细,也不包括脚本,只是一些命令名称及其作用。
布鲁诺·佩雷拉

我没有使用这些系统的经验,我只是通过使用Google进行的一些研究发现了它们(因此为什么它们只是链接)。例如,我了解了duplicity实际情况。
Portablejim

3

您应该看一下ddar主页)。

就不传输快照的相同部分而言,它是增量的。由于它处理的是快照,因此它在单词的古典意义上不是增量的。

注意: 我自己还没有尝试过(但是我相信作者)。它可能无法实现开箱即用的目的,但是页面上仍然存在更多类似的解决方案(例如ZFS),因此从起点开始,它可能会很有用。


1
我是ddar的作者(感谢提及!)。如果我正确理解了该问题,则向ddar交付一系列LVM快照将完全按照要求进行。如您所说,它处理快照而不是增量快照,但是快照将具有相同的效果,其优点是可以随意删除旧快照而不会影响新快照。
罗比·巴萨克

@robie我很高兴看到它是如何工作的,您能为我或可能正在寻求这种解决方案的任何用户提供一个很小的指南吗?
布鲁诺·佩雷拉

1

我认为您可以使用LVM的唯一理论来做到这一点,这将浪费大量的硬盘。我的理论是,您可以将根系统放在逻辑卷上,然后如果要进行测试,可以创建快照并使用新卷重新启动计算机。

LVM快照需要原始卷才能工作。这是因为新卷保留了快照和实际文件系统之间的差异。

如果将系统保持这种状态,随着新文件系统的更改,您将开始浪费磁盘空间。我不知道是否有一种方法可以合并快照和确定的文件系统。当然,您可以dd到另一个逻辑卷,但是为此,您将需要两倍于文件系统的空间以及“恢复点”与当前状态之间的差。

所有这一切都需要重新启动,并且远非自动化。

还假设有几种现代文件系统采用这种方式,例如solaris系统上的zfs或实验性btrfs。


1

这有点让我烦恼,但是听起来您想要做的一部分就是对二进制文件(例如分区映像文件)进行部分备份。有一个设计用于执行此操作的程序包(我已经读过它-尚未尝试过。)

看看bup。

https://github.com/apenwarr/bup

它可能会给您一些想法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.