在同步一个超大文件时,发现 rsync 并没有按照预期的同步一个文件。而使用md5sum
检验文件内容时,原始文件和目标文件的内容并不一样。
1、rsync
的默认算法
在man rsync
的文档里可以看到:
Rsync finds files that need to be transferred using a "quick check" algorithm (by default) that looks for files that have changed in size or in last-modified time.
Any changes in the other preserved attributes (as requested by options) are made on the destination file directly when the quick check indicates that the file』s data does not need to be updated.
即默认rsync
只会比较文件大小和最后修改时间,只要这两者一样,rsync
即认为文件相同。其它属性(包括文件内容)的不同,并不会让rsync
同步该文件!
2、用参数控制rsync
的比较算法
通过设置合适的参数,可以控制 rsync 的比较算法。事实上, rsync 有三步来比较文件:
- 比较文件大小。
- 比较文件最后修改日期。
- 比较文件内容,通过
checksum
(比如md5sum
)。
我们可以用参数来控制 rsync 执行上面的哪些步骤:
- 默认的算法只执行 1 和 2。
- 参数
--size-only
只检查 1 ,亦即只要文件一样大,即使修改日期不一样,就认为文件一样,更不会去检查文件内容。 - 参数
--ignore-times
是忽略所有检查,直接认为文件都不一样,然后总是复制文件。 - 参数
--checksum
是在 1 的基础上执行 3 ,比较文件内容。如果文件大小不一样,可以确保内容不一样。如果文件大小一样,那么直接比较文件内容,不会执行 2 中的比较修改日期。该方法最安全,但需要读取两边的文件内容,某些情况下要慢很多(尤其是最后比较出来的文件内容一样的情况)。
详细的算法可参考 TR-CS-96-05 The rsync algorithm。
该使用什么参数:
- 大部分情况下用默认参数即可。
- 如果会出现文件大小和修改时间一样,但内容不一样的情况,此时需要用
--checksum
。 - 确定文件内容大概率不一样需要同步,可以直接使用
--ignore-times
,这比--checksum
省去了检查文件内容的时间。
Q. E. D.