我使用自定义夜间备份解决方案rsync
来--link-dest
仅更新新内容,并--hard-links
忠实地呈现我的源。此外,这两个选项都有助于最大限度地减少网络流量和存储空间。
最近,我想在“媒体”目录的各个子目录中移动数百个媒体文件,而我认为最好的方法是创建一个并行目录结构,并与这些文件建立硬链接,然后根据需要将文件移动到那里,预计不需要使用额外的空间(目录条目除外),最终在现有目录名称下拥有新的目录结构。
令我惊讶的是,这个过程开始创建新文件并传输大量数据。仔细查看并操作后--dry-run
,我意识到rsync
想要做的是先传输新目录中的文件,然后为旧目录创建指向它们的硬链接(丢弃上一个备份中的现有副本),而不仅仅是从新文件创建指向旧文件的硬链接。
似乎发生的情况是,rsync
首先按字母顺序处理源文件,然后查看上一个备份中的内容。因此目录的名称很重要。当多个文件具有相同的 inode 时,第一个rsync
找到的文件将是与上一个备份硬链接或复制或更新的文件,而具有相同 inode 的后续文件将链接到第一个文件的备份。如果rsync
首先找到新文件,它将复制它,但如果找到旧文件,它将把它链接到上一个备份。
问题是除了确保名称以正确的方式排序之外,我还能做些什么。(rsync
可以查看源中具有相同 inode 的所有文件,并检查其中是否有在目标上有对应的文件,而不是仅对第一个文件执行此操作。)
一个相关的问题是我是否可以避免在备份中手动重命名目录。(我真正想要的是MyDir
将下面的文件移动到不同的子目录中。我创建了MyDir2
并在其中创建了指向 中的文件的硬链接MyDir
,然后在 中移动了内容MyDir2
,但现在我已经完成了,我希望新的目录结构位于 下MyDir
。在 中进行任何更改MyDir
都会导致文件复制。解决方法是转到我的源和最后的备份,然后在两个地方删除MyDir
并重命名MyDir2
为MyDir
。)
编辑:我尝试用一个小例子来重现这个问题,但在这种情况下,它按我想要的方式工作:当在源中找到新的硬链接时,无论排序顺序如何,它都会在目标处产生硬链接。所以现在我很困惑。备份的大小有关系吗?(我想要移动的数百个文件只是我的 3TB 备份的一小部分,其中包含 150,000 个目录中的 800,000 个文件。)
我做了什么:
我从这个开始:
source
dir2
file1
file2
然后我复制source
到dest1
。
然后我创建了dir1
和,并在它们内部创建了到和的dir3
硬链接:file1
file2
source
dir1
file1
dir2
file1
file2
dir3
file2
然后我跑了:
rsync --archive --link-dest ../dest1 --hard-links --itemize-changes source/ dest2/
created directory dest2
cd..t...... ./
cd+++++++++ dir1/
hf+++++++++ dir1/file1 => dir2/file1
cd+++++++++ dir3/
hf+++++++++ dir3/file2 => dir2/file2
与我的真实备份不同,在此示例中没有创建新文件dest2
,只有硬链接。