使用 rsync 复制数据会导致大小差异

使用 rsync 复制数据会导致大小差异

我正在切换机器,并将旧硬盘(/dev/sda4)连接到新机器上。

720G与新机器相比(),旧机器的硬盘稍微小一些( ) 736G,所以我也创建了一个稍微大一些的分区。

因此,我随后将rsync所有数据复制到新分区,如下所示:

linux-70e2:/ # time rsync -azprvl /mnt/external-disk/foo /media/sda4/

...
sent 169,237,139,987 bytes  received 24,529 bytes  24,419,185.41 bytes/sec
total size is 190,542,953,489  speedup is 1.13

real    115m30.297s
user    112m13.068s
sys     3m59.996s

数据被复制,没有错误。

但是,当我这样做时:

du -h -m -s /mnt/external-disk/foo /media/sda4/foo

我得到:

162414  /mnt/external-disk/foo
181721  /media/sda4/foo

有人能解释一下这种巨大的差异吗?为什么我没有得到相同的结果?这已经让我抓狂好几天了。还有其他几个分区,我也得到了类似的差异。

两个分区都是ext4

linux-70e2:/ # mount | grep sda4
/dev/nvme0n1p5 on /media/sda4 type ext4 (rw,relatime,data=ordered)
/dev/sda4 on /mnt/external-disk type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2)

据我所知,两个 SSD 驱动器都没有问题。其中一个是全新的。我已经用过e2fsck它们两个了。

此外,我还运行了:

find -L /mnt/external-disk type/foo -type l

并且这没有列出源目录下的任何符号链接。

这不是我第一次使用rsync这种东西,但我以前从未遇到过这种问题。请指教!

答案1

这种差异很可能是由于旧磁盘上文件较为稀疏造成的。

无论如何,我们首先检查文件和 inode 编号是否相同:

  • 两个挂载点都存在问题find <path> | wc -l。文件/目录的数量是否相同?
  • 问题df -i。inode 的数量是否相同?

如果两个问题的答案都是肯定的,那么差异可以用新磁盘上的稀疏文件来解释。但什么是稀疏文件?简而言之,稀疏文件是比它们看起来更小的普通文件。这要归功于(相对)现代文件系统的一项功能,它不是将所有零写入文件,而是设置一个标志告诉系统“这个文件(或部分文件)全是零,不要让我把它们全部写入”。

默认情况下,du报告文件占用的实际空间,而不是其表观大小。要显示表观大小,请使用du --apparent-size(有关其他选项,请参阅du 手册页

举个实际的例子,你可以使用命令创建一个稀疏文件truncate test.img -s 1G。正如所报告的ls,新创建的文件大小为 1 GB,但如果你尝试du -hs test.img,你会看到一个非常非常小的文件大小(甚至可能是零!)。这怎么可能呢?如上所述,现代文件系统有时会对应用程序“撒谎”,报告一个实际上不存在的分配大小。另一方面du -hs --apparent-size test.img将打印与相同的大小ls

当您开始写入稀疏文件时,文件系统将动态分配所需的空间。例如,发出命令dd if=/etc/services of=test.img conv=notrunc,nocreat会将一些数据写入之前全稀疏的 test.img 文件中。现在,运行du -hs test.img将报告为数据存储分配了约 600 KB。

一个显而易见但非常重要的含义是,稀疏文件支持只能针对零填充文件(或部分文件)进行优化。写入文件的那一刻,其分配的空间就开始增长。即使您将其他零写入文件,情况也是如此,除非应用程序知道如何处理稀疏文件(在这种情况下,应用程序将通知文件系统它将写入所有零,并且文件系统会进行相应的优化)。

如果你想真的预分配一些空间?那么您可以使用fallocate test.img -l 1G。如果执行ls; du -hs test.img; du -hs --apparent-size test.img,您将看到所有工具都报告相同的大小,因为文件实际上是通过调用完全分配的fallocate

简而言之,在复制过程中,可能会以不太稀疏的方式重新创建某些文件,将稀疏部分替换为“真实”零。要使用稀疏文件,rsync您必须使用该-S选项。

答案2

我以前看到过类似的差异,通常是由于驱动器的块大小不同造成的。如果原始驱动器较旧,情况尤其如此。您可以使用以下内容验证这一点。

tune2fs -l /dev/sdXX | grep -i 'block size'

答案3

您的 rsync 选项不会复制硬链接,请尝试添加-H

-H, --hard-links 此项告诉 rsync 在传输中查找硬链接文件,并将接收端的相应文件链接在一起。如果没有此选项,传输中的硬链接文件将被视为单独的文件。当您更新非空目标时,此选项仅确保在源上硬链接在一起的文件在目标上也硬链接在一起。它目前不会尝试破坏目标上源文件之间不存在的现有硬链接。但请注意,如果一个或多个额外链接的文件的内容发生变化,则它们在更新时将变为取消链接(假设您没有使用 --inplace 选项)。

稀疏文件(例如 VM 映像)也可能通过将空白替换为实际块来增加使用量。尝试使用--sparsersync 选项。

您还可以尝试使用diff来比较目录树。请参阅https://stackoverflow.com/questions/4997693/given-two-directory-trees-how-can-i-find-out-which-files-differ

相关内容