我正在使用 robocopy 和硬链接编写一个小备份脚本。我的目标是使用与 rsync 类似的概念进行差异备份,--link-dest
而无需借助第三方工具。对于那些不熟悉的人来说,这个概念是第一次备份被视为完整备份,后续备份关联使用硬链接删除上次备份中未更改的文件,并仅复制已更改的文件,这样您将获得多个完整的时间点备份目录,同时占用的磁盘空间比完整备份少得多(由于硬链接)。
我的问题是,每当我硬链接一个文件时, robocopy 都会将硬链接的文件报告为修改的,尽管我大概没有以任何方式更改它。起初我怀疑访问时间可能已更改,但事实并非如此,因为只有当我尝试复制 ACL 或所有者信息(/COPY:S
或/COPY:O
)时,文件才会被报告为已修改。
这就是我尝试做的事情:
有一个要复制的源目录结构
mkdir C:\BackupSource type nul > C:\BackupSource\myfile.txt
有一个用于备份的目标根目录
mkdir C:\BackupTarget
运行第一次完整备份
我在脚本中使用了更多标志,但这些足以触发行为。robocopy C:\BackupSource C:\BackupTarget\1 /MIR /COPY:DATSO
检查文件是否是最新的
(不是脚本的一部分,只是为了回答问题)robocopy C:\BackupSource C:\BackupTarget\1 /MIR /COPY:DATSO /L
这告诉我该文件已被跳过,这是有道理的,因为此时它还没有被修改。
为后续备份创建目录结构
这将创建一个与上一次备份相同的空目录结构。我将在下一步中遍历上一次备份并创建硬链接。robocopy C:\BackupTarget\1 C:\BackupTarget\2 /MIR /CREATE /DCOPY:DAT /XF *
硬链接文件
这部分在脚本中显然有点复杂,因为它会下降到子目录中,但一个文件对于这个问题来说就足够了。mklink /H C:\BackupTarget\2\myfile.txt C:\BackupTarget\1\myfile.txt
现在,我认为我没有对任何目录中的文件进行任何修改。CreateHardLinkW 函数(我真的在脚本中使用)说
安全描述符属于硬链接指向的文件...
您不能根据每个硬链接为文件提供不同的安全描述符...
此功能不会修改要链接到的文件的安全描述符...
然而,当我现在检查文件是否已被修改,robocopy 告诉我硬链接和它指向的原始备份中的文件都已被修改。
robocopy C:\BackupSource C:\BackupTarget\1 /MIR /COPY:DATSO /L
robocopy C:\BackupSource C:\BackupTarget\2 /MIR /COPY:DATSO /L
我检查了标准属性、创建/修改/访问时间、ACL 和所有者,它们完全相同。如果我只使用/COPY:DAT
(这是默认设置),robocopy 会告诉我没有修改,这让我相信硬链接做改变安全描述符中的一些内容。
当我像平常一样运行后续备份命令时
robocopy C:\BackupSource C:\BackupTarget\2 /MIR /COPY:DATSO
robocopy 告诉我它修改了我所有的文件,但我认为它只是修复了安全描述符,因为备份比第一次完整备份快得多。此外,当我使用
fsutil hardlink list C:\BackupTarget\2\myfile.txt
它报告说该文件仍然是一个指向我之前指向的同一文件的硬链接。这个问题似乎只是表面上的问题,但是当 robocopy 报告每次备份中的所有文件都被修改时,这些日志的价值就大大降低了。
当我将硬链接指向文件时,为什么 robocopy 会认为文件的安全描述符已被修改?在硬链接之后和启动后续 robocopy 之前,我该如何防止或修复它?