可能有人认为,--link-dest
在所有情况下都可以对相同文件进行操作。但是,即使文件已过期/具有不同的内容,当文件存在时也不会。
因此,在rsync手册页上--link-dest
:
“此选项在复制到空的目标层次结构中时效果最佳,因为rsync将现有文件视为权威文件(因此,当目标文件已存在时,rsync永远不会在链接目标目录中查找)”
这意味着,如果y/file
与源存在相同且z/file
已过期,
rsync -a --del -link-dest=y source:/file z
将导致使用两个inode(和磁盘空间的两倍)y/file
和z/file
,它们将具有相同的内容和日期戳。
之所以遇到此问题,是因为我基本上每天备份一次,而该脚本每天运行一次:
mv $somedaysago $today;
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today
因为我的备份最多可以存储1000万个文件,所以这样做rm -rf $olddir; rsync source:$dir newdir
会花费太长时间(尤其是每天仅更改0.5%的文件时,会导致删除和创建10M目录条目只是为了处理5万个新文件或更改过的文件,这会使我备份未在第二天及时完成)。
这是情况的演示:
a
是我们的来源,1
通过4
我们的编号备份:
$ mkdir -p 1 2; echo foo > 1/foobar; cp -lrv 1/* 2
`1/foobar' -> `2/foobar'
$ ls -i1 */foobar
1053003 1/foobar
1053003 2/foobar
$ mkdir a; echo quux > a/foobar
$ mv 1 3; rsync -avPhyH --del --link-dest=../2 a/ 3
sending incremental file list
./
foobar
5 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/2)
sent 105 bytes received 34 bytes 278.00 bytes/sec
total size is 5 speedup is 0.04
$ ls -i1 */foobar
1053003 2/foobar
1053007 3/foobar
1053006 a/foobar
$ mv 2 4; rsync -avPhyH --del --link-dest=../3 a/ 4
sending incremental file list
./
foobar
5 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/2)
sent 105 bytes received 34 bytes 278.00 bytes/sec
total size is 5 speedup is 0.04
$ ls -il1 */foobar
1053007 -rw-r--r-- 1 math math 5 Mar 30 00:57 3/foobar
1053008 -rw-r--r-- 1 math math 5 Mar 30 00:57 4/foobar
1053006 -rw-r--r-- 1 math math 5 Mar 30 00:57 a/foobar
$ md5sum [34a]/foobar
d3b07a382ec010c01889250fce66fb13 3/foobar
d3b07a382ec010c01889250fce66fb13 4/foobar
d3b07a382ec010c01889250fce66fb13 a/foobar
现在我们有2个备份,a/foobar
在所有方面都是相同的,包括时间戳,但是占用了不同的inode。
可能会想到一种解决方案--delete-before
,这将失去增量扫描的优势,但这无济于事,因为该文件不会被删除,但在可能进行增量复制时用作基础。
有人可能会进一步猜测,然后我们可以使用来关闭此增量副本对冲--whole-file
,但这对算法没有任何帮助,无法获得我们想要的东西。
我认为此行为是rsync中的另一个错误,可以通过仔细选择各种命令参数来解释有益的行为,但是所需的结果不可用。
不幸的是,一个解决方案将是从单个rsync作为原子操作转移到试运行-n
,对其进行日志记录,将该日志作为输入进行处理以手动预删除所有更改的文件,然后运行rsync --link-dest
以获取我们想要的文件,这是一个很大的麻烦与单个干净的rsync相比。
附录:尝试在生产服务器上进行备份之前进行预链接$yesterday
并$today
在备份服务器上进行备份,rsync --link-dest=../$yesterday $yesterday/ $today
但结果却是相同的- 任何以任何方式存在的文件,即使长度为0,也永远不会被删除并链接到一起,而是整个文件将使用新的inode从sourcedir创建新副本,并使用更多磁盘空间。
寻找pax(1)
一种可能的备份前链接解决方案。
--delete-after
很好,但与当前问题无关。复制完成后,源中缺少的文件将被删除。我要说明的问题与今天进行的备份有关,该备份与昨天的备份相同,但是针对的是一个旧的,已过期的旧文件,该文件未链接到昨天的inode,但作为新文件存储,是昨天的总磁盘空间的两倍考虑相同的副本。
rsnapshot
吗?另外,考虑编写一个小的脚本来重新链接“相同”文件。我在我的系统上都做。
hardlink(1)
慢(比rsync的元数据扫描慢15倍);pax
速度更快,但硬盘驱动器磁头将旧备份与新备份进行比较。rsync -n
要获得增量列表,就意味着要两次击中生产服务器(扫描1000万个文件比复制5万个更改的影响要大得多)。不适用于在rsync中邮寄有关选项的列表以允许此操作。
--delete-after
在这种使用情况下使用,这是怎么回事?