仅在更改时恢复分区

仅在更改时恢复分区

我写了一个脚本,用于从以前的转储中恢复分区dd。基本上它调用以下行:

dd if=stored_image.img of=/dev/sdb1 bs=1M

恢复大约需要 5 分钟(20GB 数据),如果未进行任何更改,最好只恢复映像。当然,我现在可以使用哈希检查整个分区并将其与前一个分区进行比较,但哈希生成速度仅与我从设备读取的速度一样快,因此也md5sum /dev/sdb1需要大约 5 分钟来计算...

现在的问题是:有没有什么方法可以非常快速地检测磁盘上的变化?(比如不到半分钟)没有必要 100% 确定,但至少 90% 的准确率应该没问题。

答案1

这听起来可能像是一个“繁重”的解决方案,但我建议使用 mdadm。mdadm 有一项称为“写入意图位图”的功能。为了简单起见,您可以将其视为一个由 1 和 0 组成的数组,其中每个数字代表磁盘上给定的数据量。它所代表的数据量取决于位图的大小。

假设您有 20GB 的数据,并且您有一个 20 位的位图,每个位代表 1GB 的数据。每次写入 mdadm RAID 时,1GB 部分的相应位都会切换为 1。

我现在建议您创建一个带有写入意图位图的“假 RAID 1”,并且时不时地想要“同步”您的图像,只需将图像“连接”到 mdadm raid。然后,mdadm 将确保写入意图位图为 1 的所有部分并显示“此部分很脏”,它会自动将数据同步到您的图像。

我为您创建了一个小型 bash 脚本作为示例:

# Create 2 images (loop1 could later be your /dev/sdb1)
fallocate -l 1G loop1.img
fallocate -l 1G loop2.img

# Create loop deveices for mdadm
losetup /dev/loop1 loop1.img   #### you don't need this step for /dev/sdb1 of course

# Create a RAID 1 with only loop1 or sdb1, replace /dev/md/<bitmap> with a suiteable name
mdadm --create -l 1 -n 2 --bitmap=internal --bitmap-chunk=128 /dev/md/bitmap /dev/loop1  missing

因此调用“cat /proc/mdstat”应该返回类似的内容:

md121 : active raid1 loop1[0]
  1047552 blocks super 1.2 [2/1] [U_]
  bitmap: 4/4 pages [16KB], 128KB chunk

[U_] 表示第一个设备 (loop1) 是“U”,第二个设备缺失 (_)。使用 --bitmap-chunk=,您可以确定每个位的数据块有多大。较小的值可以提供更好的重建速度/粒度,较大的值可以减少写入速度的影响,从而保持位图同步。

如果您想同步您的图像,只需从中创建一个循环设备并将其添加到突袭中:

losetup /dev/loop2 loop2.img
mdadm --add /dev/md/bitmap /dev/loop2

/proc/mdstat 将会显示它正在恢复您的图像,第一次是完整复制:

md121 : active raid1 loop2[2] loop1[0]
      1047552 blocks super 1.2 [2/1] [U_]
      [===>.................]  recovery = 18.7% (196608/1047552) finish=0.1min speed=98304K/sec
      bitmap: 0/4 pages [0KB], 128KB chunk

您可以始终将映像留在 RAID1 中以保持同步,也可以在同步完成后将其删除。如果您想编写脚本,您可能会发现检查 /sys/block/md121/md/sync_action 是否为“idle”很有用。这意味着恢复已完成。

现在您可以通过以下方式删除图像:

mdadm --fail /dev/md/bitmap /dev/loop2
mdadm --remove /dev/md/bitmap /dev/loop2

改变几个字节后:

dd if=/dev/urandom of=/dev/md/bitmap bs=4k count=1k seek=1000

您会看到位图上有脏位:

md121 : active raid1 loop1[0]
  1047552 blocks super 1.2 [2/1] [U_]
  bitmap: **1/4 pages** [4KB], 128KB chunk

重新添加图像将恢复图像,并且仅同步脏部分没有时间......

mdadm --re-add /dev/md/bitmap /dev/loop2
sync

输出应该是:

md121 : active raid1 loop2[2] loop1[0]
  1047552 blocks super 1.2 [2/2] [UU]
  bitmap: **0/4 pages** [0KB], 128KB chunk

我希望这有帮助。

相关内容