我正在切换机器,并将旧硬盘( /dev/sda4 )连接到新机器。
旧机器的硬盘( 736G )比新机器( 736G )要小一些,所以我创build了一个更大的分区。
于是,我运行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)
据我所知,这两个硬盘都是没有问题的。 其中之一是全新的。 我已经在他们两个上运行了e2fsck 。
另外,我跑了:
find -L /mnt/external-disk type/foo -type l
这不会列出源目录下的任何符号链接。
这不是我第一次使用rsync进行这种事情,但是我以前从来没有遇到过这种问题。 请指教!
这种差异很可能是由旧磁盘上更稀疏的文件造成的。
无论如何,我们先来检查一下这个文件和inode数字是否一致:
find <path> | wc -l find <path> | wc -l在两个挂载点上。 文件/目录的编号是否相同? df -i 。 inode的数量是否相同? 如果对这两个问题的答案是肯定的,则可以通过新磁盘上更稀疏的文件来解释差异。 但是什么是稀疏文件? 简而言之,稀疏文件是比正常文件小的文件。 这是可以感谢(相对)现代文件系统的function,而不是写一个文件的所有零,而只是设置一个标志告诉系统“这个文件(或部分)是满零,不要让我写商场”。
默认情况下, du报告文件占用的真实空间,而不是明显的大小。 要显示明显的大小,请使用du --apparent-size (有关其他选项,请参阅du手册页 )
举一个实际的例子,你可以使用truncate test.img -s 1G命令创build一个稀疏文件。 正如ls所报告的那样,新创build的文件大小为1 GB,但如果您尝试使用du -hs test.img ,则会看到非常非常小的文件大小(甚至可能为零)。 怎么可能? 如上所述,现代文件系统有时对应用程序“撒谎”,报告一个实际上不存在的分配的大小。 另一方面, du -hs --apparent-size test.img将打印与ls相同的大小。
当您开始写入稀疏文件时,文件系统将dynamic分配所需的空间。 例如,发出dd if=/etc/services of=test.img conv=notrunc,nocreat会将一些数据写入先前全稀疏的test.img文件中。 现在,运行du -hs test.img会报告为数据存储分配的du -hs test.img KB。
一个显而易见的但非常重要的含义是稀疏文件支持只能针对零填充文件(或部分文件)进行优化。 在写入文件的同时,分配的空间也开始增长。 如果您将其他零写入文件,除非应用程序知道如何处理稀疏文件(在这种情况下,应用程序会通知文件系统它将写入全零,并且文件系统优化),否则这是真实的事件。
如果你想真的预先分配一些空间呢? 然后你可以使用fallocate test.img -l 1G 。 如果你执行ls; du -hs test.img; du -hs --apparent-size test.img ls; du -hs test.img; du -hs --apparent-size test.img ls; du -hs test.img; du -hs --apparent-size test.img ,你会发现所有的工具报告的是相同的大小,因为这个文件是通过fallocate调用真正完全分配的。
简而言之,在复制过程中,可能会以稀疏的方式重新创build一些文件,用“真正的”零代替稀疏部分。 要使用rsync稀疏文件,你必须使用-S选项。
当我看到过去的差异时,通常是由于驱动器块大小的差异。 如果原始驱动器较旧,则更是如此。 您可以使用以下validation。
tune2fs -l /dev/sdXX | grep -i 'block size'
您的rsync选项不会复制硬链接,请尝试添加-H
-H,–hard-links这告诉rsync在传输中查找硬链接的文件,并将接收端的相应文件链接在一起。 如果没有这个选项,传输中的硬链接文件将被视为独立文件。 在更新非空目标时,此选项仅确保在源上硬链接在一起的文件在目标上硬链接在一起。 它目前没有努力打破在源文件之间不存在的已经存在的硬链接。 但是,请注意,如果一个或多个额外链接的文件有更改的内容,它们将在更新时取消链接(假设您没有使用–inplace选项)。
稀疏文件,例如虚拟机映像,也可以通过用真实块代替虚拟空间来扩大使用量。 尝试在rsync中使用--sparse选项。
你也可以尝试使用diff来比较目录树。 见https://stackoverflow.com/questions/4997693/given-two-directory-trees-how-can-i-find-out-which-files-differ