我正在切换机器,并将旧硬盘(/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 映像)也可能通过将空白替换为实际块来增加使用量。尝试使用--sparse
rsync 选项。
您还可以尝试使用diff
来比较目录树。请参阅https://stackoverflow.com/questions/4997693/given-two-directory-trees-how-can-i-find-out-which-files-differ