这是一个扩展为什么 rsync 尝试复制已经是最新的文件?
我正在尝试使用该--copy-devices
补丁来rsync
复制整个磁盘驱动器并将其作为映像存储在另一台计算机上。
复制似乎已正确运行,但是,当我rsync
使用相同的值再次运行时,它似乎每次都会再次复制一些数据。
我rsync
带着冗长的内容运行并得到了这个:
$ sudo rsync -vvz --partial --progress --copy-devices /dev/sdb me@otherserver:/backupdisks/mydisk.img
opening connection using: ssh -l me otherserver rsync --server -vvze.Lsfx --partial --copy-devices . /backupdisks/mydisk.img (11 args)
me@otherserver's password:
delta-transmission enabled
sdb
320,071,851,520 100% 63.47MB/s 1:20:09 (xfr#1, to-chk=0/1)
total: matches=2441955 hash_hits=2441955 false_alarms=204015955 data=0
sent 188 bytes received 21,979,001 bytes 2,837.31 bytes/sec
total size is 0 speedup is 0.00
我知道 rsync 按时间确定更改,但磁盘在 rsync 之间没有更改(它如何确定磁盘的修改时间?)但是,远程映像上的时间每次都会更新。所以这可能是问题所在。
另一种可能性是磁盘有一个坏扇区,每次返回不同的值并否定正在使用的任何校验和。
我的问题有两个:
我的映像是否已成功传输?如果是,为什么当我再次运行它时,它会重新传输大部分磁盘? (这也可以作为我的推论问题的一部分得到部分回答rsync 输出中的“matches”、“hash_hits”和“false_alarms”是什么,“data=0”是否意味着成功?)
我是否缺少一个开关来使其正常工作? (也许
--checksum
?)是否可以列出 rsync 算法使用的块级故障?
答案1
默认情况下,rsync 按大小和时间戳比较文件,但设备没有大小,因此必须使用 delta 算法来计算差异,这在本节中进行了描述。技术报告。松散地,远程文件被分成选定大小的块,并且这些块的校验和被发送回。本地文件同样以块为单位进行校验和,并与列表进行比较。然后,远程设备被告知如何重新组装它必须重新制作文件的块,并且发送不匹配的块的数据。
您可以通过仅针对带选项的 deltasum 算法在级别 3 请求调试输出来看到这一点--debug=deltasum3
。您可以指定块大小以-B
简化数字。例如,对于已经复制过一次的文件,第二次运行
rsync -B 100000 --copy-devices -avv --debug=deltasum3 --no-W /dev/sdd /tmp/mysdd
生成如下所示的输出,显示每个块的校验和:
count=164 rem=84000 blength=100000 s2length=2 flength=16384000
chunk[0] offset=0 len=100000 sum1=61f6893e
chunk[1] offset=100000 len=100000 sum1=32f30ba3
chunk[2] offset=200000 len=100000 sum1=45b1f9e5
...
然后您可以看到它与其他设备的校验和相当简单地匹配,因为没有差异:
potential match at 0 i=0 sum=61f6893e
match at 0 last_match=0 j=0 len=100000 n=0
potential match at 100000 i=1 sum=32f30ba3
match at 100000 last_match=100000 j=1 len=100000 n=0
potential match at 200000 i=2 sum=45b1f9e5
match at 200000 last_match=200000 j=2 len=100000 n=0
...
最后该data=
字段为 0,表示没有发送新数据。
total: matches=164 hash_hits=164 false_alarms=0 data=0
如果我们现在通过覆盖文件的中间部分来损坏副本:
echo test | dd conv=block,notrunc seek=80 bs=100000 of=/tmp/mysdd
touch -r /dev/sdd /tmp/mysdd
然后 rsync 调试向我们显示了块 80 的新校验和,但没有匹配。我们从第 79 场比赛转到第 81 场比赛:
chunk[80] offset=8000000 len=100000 sum1=a73cccfe
...
potential match at 7900000 i=79 sum=58eabec6
match at 7900000 last_match=7900000 j=79 len=100000 n=0
potential match at 8100000 i=81 sum=eba488ba
match at 8100000 last_match=8000000 j=81 len=100000 n=100000
最后我们data=100000
表明必须发送一个全新的数据块。
total: matches=163 hash_hits=385 false_alarms=0 data=100000
对于无法匹配的损坏块校验和,匹配数已减少 1。也许哈希命中率上升是因为我们失去了顺序匹配。
如果我们看更远在同一份技术报告中,显示了一些测试结果误报 被描述为“32 位滚动校验和匹配但强校验和不匹配的次数”。每个块都有一个简单的校验和和一个 md5 校验和(旧版本中为 md4)。简单的校验和很容易使用哈希表进行搜索,因为它是一个 32 位整数。一旦匹配到某个条目,还会比较较长的 16 字节 md5 校验和,如果不匹配则误报,继续搜索。
我的示例使用一个非常小的(且旧的)16MB 的 USB 密钥设备,最小哈希表大小为 2**16,即 65536 个条目,因此当保存我拥有的 164 个块条目时,它非常空。如此多的误报是正常的,而且比其他任何事情都更能表明效率。
答案2
您需要考虑使用rsync --partial --inplace
以及其他选项,因为否则它将在工作时在目标端制作光盘映像的完整副本。我也一直在使用,-B 4096
因为它是设备的自然扇区大小,而 rsync 默认块大小对于此类操作来说太小。
为了再次检查图像是否全部正确复制,我建议sha1sum
在源端和目标端都进行独立的操作。这应该不是必需的,但如果您想确定的话,这很简单并且您可以信任它。我假设您的源磁盘不是实时安装或类似的东西,否则所有的赌注都会被取消,并且没有可靠的方法来发送它。