如果旧文件已经存在,如何使rsync用--link-dest选项链接相同文件?


11

可能有人认为,--link-dest在所有情况下都可以对相同文件进行操作。但是,即使文件已过期/具有不同的内容,当文件存在时也不会。

因此,在rsync手册页上--link-dest

“此选项在复制到空的目标层次结构中时效果最佳,因为rsync将现有文件视为权威文件(因此,当目标文件已存在时rsync永远不会在链接目标目录中查找)”

这意味着,如果y/file与源存在相同且z/file已过期,

rsync -a --del -link-dest=y source:/file z

将导致使用两个inode(和磁盘空间的两倍)y/filez/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在这种使用情况下使用,这是怎么回事?
gogoud

1
--delete-after很好,但与当前问题无关。复制完成后,源中缺少的文件将被删除。我要说明的问题与今天进行的备份有关,该备份与昨天的备份相同,但是针对的是一个旧的,已过期的旧文件,该文件未链接到昨天的inode,但作为新文件存储,是昨天的总磁盘空间的两倍考虑相同的副本。
数学

不确定您要问的是什么。你考虑过了rsnapshot吗?另外,考虑编写一个小的脚本来重新链接“相同”文件。我在我的系统上都做。
roaima 2015年

1
如果您在这里找不到所需的答案,则可以在rsync列表中发布。rsync开发人员会定期与许多高级用户一起回答问题。您可以通过list.samba.org/mailman/listinfo/rsync找到它们。我主要潜伏在那里,学到很多东西。

rsnapshot不会回收旧的备份-我需要:如果我有2个月和2个月+1天的旧备份,则可以循环一个作为新目标。由于每天大约有5%的文件更改,因此我创建了50K硬链接,而不是10M。此速度差异允许每晚备份5台服务器,而不能。 hardlink(1)慢(比rsync的元数据扫描慢15倍);pax速度更快,但硬盘驱动器磁头将旧备份与新备份进行比较。rsync -n要获得增量列表,就意味着要两次击中生产服务器(扫描1000万个文件比复制5万个更改的影响要大得多)。不适用于在rsync中邮寄有关选项的列表以允许此操作。
2015年

Answers:


12

(从问题编辑转换为)

这可以通过升级rsync解决。现在,版本3.1.1或更高版本将--link-dest用一个硬链接文件替换目标和目录中的相同文件。节省大量空间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.