![仅在更改时恢复分区](https://linux22.com/image/1409012/%E4%BB%85%E5%9C%A8%E6%9B%B4%E6%94%B9%E6%97%B6%E6%81%A2%E5%A4%8D%E5%88%86%E5%8C%BA.png)
我写了一个脚本,用于从以前的转储中恢复分区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
我希望这有帮助。