Я переключаю машины и подключил старый жесткий диск ( / 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
для такого рода вещей, но у меня никогда раньше не было такой проблемы. Пожалуйста, посоветуйте!
Несоответствие, скорее всего, вызвано более редким заполнением файла на старом диске.
В любом случае, давайте сначала проверим, что номера файла и inode совпадают:
find | wc -l
на обеих точках монтирования. Совпадает ли номер файла / каталога? df -i
. Совпадает ли количество индексных дескрипторов? Если ответ на оба вопроса утвердительный, то разницу можно объяснить меньшим количеством файлов на новом диске. Но что такое разреженные файлы? Короче говоря, разреженные файлы - это обычные файлы, размер которых меньше, чем кажется. Это возможно благодаря функции (относительно) современных файловых систем, которые вместо записи всех нулей в файл просто устанавливают флаг, сообщающий системе: «этот файл (или его часть) заполнен нулями, не позволяйте мне писать их все ".
По умолчанию du
сообщает реальное пространство, занятое файлом, а не его видимый размер. Чтобы показать видимый размер, используйте du --apparent-size
(другие параметры см. В du manpage )
В качестве практического примера вы можете создать разреженный файл с помощью команда обрезать test.img -s 1G
. Как сообщает ls
, размер вновь созданного файла составляет 1 ГБ, но если вы попробуете 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 КБ, выделенных для хранения данных.
Очевидное, но очень важное значение состоит в том, что поддержка разреженных файлов может быть оптимизирована только для файлов с нулевым заполнением (или их части). В тот же момент, когда вы пишете в файл, его выделенное пространство начинает расти. Это истинное событие, если вы записываете в файл другие нули, если только приложение не знает, как обрабатывать разреженные файлы (в этом случае приложение сообщит файловой системе, что она собирается записать все нули, и файловая система оптимизируется соответственно).
Что, если вы хотите действительно предварительно выделить место? Затем вы можете использовать fallocate test.img -l 1G
. Если вы выполните ls; du -hs test.img; du -hs --apparent-size test.img
, вы увидите, что все инструменты сообщают один и тот же размер, потому что файл действительно был полностью выделен вызовом fallocate
.
В Короче говоря, возможно, что во время копирования какой-то файл был воссоздан менее разреженным образом, заменив разреженные разделы «настоящими» нулями. Чтобы использовать разреженный файл с rsync
, вам нужно было использовать параметр -S
.
Когда я видел подобные различия в прошлом, это обычно происходило из-за разницы в размере блока дисков. Это особенно актуально, если исходный диск старше. Вы можете проверить это следующим образом.
tune2fs -l /dev/sdXX | grep -i 'block size'
Ваши параметры rsync не будут копировать жесткие ссылки, попробуйте добавить -H
-H, --hard-links Это говорит rsync искать жестко связанные файлы в передаче и связывать вместе соответствующие файлы на принимающей стороне. Без этой опции жестко связанные файлы при передаче обрабатываются как отдельные файлы. Когда вы обновляете непустое место назначения, эта опция только гарантирует файлы, жестко связанные между собой в источнике, жестко связаны вместе в месте назначения. В настоящее время он НЕ пытается разорвать уже существующие жесткие ссылки в месте назначения, которые не существуют между исходными файлами. Однако обратите внимание, что если один или несколько файлов с дополнительными ссылками имеют изменения содержимого, они будут отключены при обновлении (при условии, что вы не используете параметр --inplace).
Разреженные файлы, такие как образы виртуальных машин, также могут быть раздувание использования путем замены пустот настоящими блоками. Попробуйте использовать параметр - sparse
с rsync.
Вы также можете попробовать использовать diff
для сравнения деревьев каталогов. См. https://stackoverflow.com/questions/4997693/given-two-directory-trees-how-can-i-find-out-which-files-differ