如何制作和恢复硬盘的增量快照

Bru*_*ira 13 filesystem backup

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

我只是喜欢它的功能之一是虚拟机快照,它可以保存虚拟机的状态,并且可以在您做错了什么时将其恢复到昔日的辉煌,而不会出现任何问题并且不会消耗您的所有硬盘空间。

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

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

为了简单描述我想要什么,它应该是dd文件系统的映像,但它不仅是完整备份,还可以创建增量备份。


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

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

它不需要每天,甚至不需要时间表。偶尔运行一次,让它发挥作用,最好是基于 RAW 而不是基于文件副本。


Por*_*jim 14

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

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

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


cprofitt 给出的流程包括:

  1. 旋转备份为新备份创建一个位置。(昨天的“今天备份”变成“昨天的备份”,两天前的“昨天备份”变成“两天前的备份”等等)

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


一个说明性的例子

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

在此处输入图片说明

过程是这样的:

  1. 有系统快照。

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

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

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

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

  6. 再次同步。(重复步骤 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 ;
Run Code Online (Sandbox Code Playgroud)

现在完整的脚本在这里有完整的解释(如 cprofitt 链接),它更彻底,但基本上如上。另一个脚本用于对快照进行分组,而 cprofitt 回答的另一部分谈到使该过程自动化(使用 cron)并验证备份是否成功。

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


要恢复整个批次,请将最新的快照(或以前的快照)复制回您进行备份的目录。

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

备份媒体可以是外部硬盘驱动器(必须是 ext2/ext3/ext4)。如果您正在备份/(主要是/boot, /home,/etc /root/usr),那么说...

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

  2. 卸载驱动器。

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

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

  5. 做一个备份(只是为了确定)

  6. 断开驱动器并开始旅行......

  7. 意识到笔记本电脑和熔岩不能混合。

  8. 使用运行 live cd 的新笔记本电脑,格式化内部驱动器,安装外部驱动器,然后cp -a /media/external/snapshot-0/* /media/internal-drive(假设快照 0 是最新快照)

  9. 将 grub 安装到 MBR(是的,它必须是单独的) - 或用于dd备份 mbr,就像 cprofitt 在他的答案底部所说的那样。

  10. 重启。

脚本需要改进(只得到你想要的东西)并且程序 aove 假设你没有/home分区。如果您确实(或曾经)在磁盘上创建了一个新磁盘并mount /dev/sdxy /media/external/home在复制之前将其安装到位。


cpr*_*itt 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;
Run Code Online (Sandbox Code Playgroud)

第二个:

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;
Run Code Online (Sandbox Code Playgroud)

根据您的需要创建脚本后,将其添加到 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)
Run Code Online (Sandbox Code Playgroud)

如果您希望它每小时运行一次,您可以每小时添加一个 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
Run Code Online (Sandbox Code Playgroud)
  1. 在 /etc/rsnapshot.conf 中定义目标备份目录,如下所示。在这个例子中,

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

    纳米 /etc/rsnapshot.conf

    备份 /home/ 本地主机/

  2. 测试 rsnapshot 配置

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

# rsnapshot configtest
Syntax OK
Run Code Online (Sandbox Code Playgroud)
  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/
Run Code Online (Sandbox Code Playgroud)
  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
Run Code Online (Sandbox Code Playgroud)
  1. 为 rsnapshot 添加 Crontab 条目

一旦您确认在 rsnapshot cwrsync 实用程序中正确设置了 rsync 每小时和每日备份配置,就可以在 crontab 中设置此小狗,如下所示。

# crontab -e
0 */4 * * * /usr/local/bin/rsnapshot hourly
30 23 * * * /usr/local/bin/rsnapshot daily
Run Code Online (Sandbox Code Playgroud)

来源: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
Run Code Online (Sandbox Code Playgroud)

备份操作系统:

# mkdir /backups
# mount nfsserver:/backups/<servername> /backups


# cd /
# tar cfz /backups/system.tar.gz --exclude /mnt --exclude /proc --exclude /backups
Run Code Online (Sandbox Code Playgroud)

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

  • 你所有的答案看起来都很好,没有问题,但不是我要问的,任何方法都不会恢复 MBR 并且 `dd` 不是增量的。这些都不是我要问的。寻找最后 10% 可能很有趣,但所有其余的信息转储实际上都不是。 (2认同)