我在一个不可用的文件系统(ext4)上有一个文件夹reflink
,我知道它包含许多具有相同块的文件。
我想将该目录移动/复制到 XFS 文件系统,同时对它们进行重复数据删除。 (即,如果复制文件的块已经存在于另一个文件中,我不想实际复制它,而是使第二个块引用指向新文件中的块。)
当然,一种选择是首先将所有文件复制到 XFS 文件系统,duperemove
在那里运行它们,从而在事后删除重复项。小问题:这可能会变得耗时,因为目标文件系统的随机访问速度不那么快。
因此,我希望复制文件的进程已经负责告诉内核,嘿,该块是已经存在的其他块的副本。
这样的事可能吗?
答案1
我将评论移至答案,以便有更多空间。
不知道有没有办法可以复制。我希望有,因为我同步了很多驱动器并且制作了很多引用链接文件副本。 Btrfs 支持“发送”机制,我认为该机制可以进行重复数据删除。不过我在大多数事情上都使用 XFS。
我看过的重复数据删除实用程序速度很慢。不仅慢,慢得令人难以置信。至少在机械驱动器上几乎不可能使用。原因是因为操作是完全同步的,所以绝对会锤击磁盘。
我一直想编写一个使用缓存的实用程序(可能需要修补内核)。它会不太安全,但速度更快,使其真正可用。我正在等待有人这样做,并且希望听到任何此类实用程序(如果存在)。
我尚未尝试的另一个选项是将驱动器连接到虚拟机并在其中运行重复数据删除。然后您可以在后端启用强制“不安全”缓存。这当然是不安全的,但希望能更快。
答案2
编辑:这不是问题的答案,而是未提出的问题的答案(如何检测和取消分配重复文件)
我的方法是创建一个目录,其中包含一个 hadlink,它是每个文件的哈希值。
如果哈希已经存在,我用哈希中的硬链接替换该文件,如果哈希文件不存在,我从哈希目录中的文件创建一个新的硬链接。
像这样的东西:
#!/bin/bash
dupes=/mnt/xfs/.dupes_dir
for x in "$@"
do
sha=$( sha1sum "$x" | cut -d\ -f1 )
if [ -e $dupes/$sha ]
then
ln -f $dupes/$sha "$x"
else
ln "$x" $dupes/$sha
fi
done