Estou trocando de máquina e conectei o disco rígido antigo ( /dev/sda4
) à nova máquina.
A máquina antiga tinha um disco rígido um pouco menor ( 720G
), comparado ao novo ( 736G
), então criei uma partição um pouco maior também.
Então, corri rsync
para copiar todos os dados para a nova partição, conforme mostrado abaixo:
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
Os dados são copiados sem erros.
No entanto, quando eu faço:
du -h -m -s /mnt/external-disk/foo /media/sda4/foo
Eu recebo:
162414 /mnt/external-disk/foo
181721 /media/sda4/foo
Alguém poderia explicar essa enorme diferença? Por que não estou obtendo os mesmos resultados? Isso está me deixando louco por dias agora. Existem algumas outras partições também e estou obtendo discrepâncias semelhantes também.
Ambas as partições são 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)
Que eu saiba, não há nada de errado com ambas as unidades que são SSDs. Um deles é novo. Eu corri e2fsck
em ambos.
Além disso, eu corri:
find -L /mnt/external-disk type/foo -type l
e isso não lista nenhum link simbólico abaixo do diretório de origem.
Não é a primeira vez que uso rsync
para esse tipo de coisa, mas nunca tive esse tipo de problema antes. Por favor informar!
A discrepância provavelmente é causada por um arquivo mais esparsamente preenchido no disco antigo.
De qualquer forma, vamos primeiro verificar se os números de arquivo e inode são os mesmos:
find <path> | wc -l
em ambos os pontos de montagem. O número de arquivo/diretório é o mesmo?df -i
. O número de inodes é o mesmo?Se a resposta para ambas as perguntas for sim, a diferença pode ser explicada por um arquivo mais esparso no novo disco. Mas o que são arquivos esparsos? Resumindo, arquivos esparsos são arquivos normais menores do que parecem. Isso é possível graças a um recurso de sistemas de arquivos (relativamente) modernos que, em vez de gravar todos os zeros em um arquivo, simplesmente definem um sinalizador informando ao sistema "esse arquivo (ou parte dele) está cheio de zeros, não me deixe escrever o Shopping".
Por padrão,
du
informa o espaço real ocupado pelo arquivo, e não o tamanho aparente. Para mostrar o tamanho aparente, usedu --apparent-size
(para outras opções, consulte du manpage )Para um exemplo prático, você pode criar um arquivo esparso usando o comando
truncate test.img -s 1G
. Conforme relatado porls
, o arquivo recém-criado tem 1 GB de tamanho, mas se você tentardu -hs test.img
, verá um tamanho de arquivo muito, muito pequeno (possivelmente até zero!). Como isso é possível? Conforme declarado acima, o sistema de arquivos moderno às vezes "mente" para os aplicativos, relatando um tamanho alocado que não existe na realidade. Do outro ladodu -hs --apparent-size test.img
, imprimirá o mesmo tamanho quels
.À medida que você começa a gravar em um arquivo esparso, o sistema de arquivos aloca dinamicamente o espaço necessário. Por exemplo, a emissão
dd if=/etc/services of=test.img conv=notrunc,nocreat
gravará alguns dados no arquivo test.img anteriormente totalmente esparso. Agora, a execuçãodu -hs test.img
relatará os ~600 KB alocados para armazenamento de dados.Uma implicação óbvia, mas muito importante, é que o suporte a arquivos esparsos pode ser otimizado apenas para arquivos preenchidos com zero (ou parte deles). No mesmo momento em que você escreve em um arquivo, o espaço alocado começa a crescer. Este é um evento verdadeiro se você escrever outros zeros no arquivo, a menos que o aplicativo saiba como lidar com arquivos esparsos (neste caso, o aplicativo avisará o sistema de arquivos que gravará todos os zeros e o sistema de arquivos será otimizado de acordo).
E se você realmente quiser pré- alocar algum espaço? Então você pode usar
fallocate test.img -l 1G
. Se você executarls; du -hs test.img; du -hs --apparent-size test.img
, verá que todas as ferramentas informam o mesmo tamanho, porque o arquivo foi realmente totalmente alocado pelafallocate
chamada.Em suma, é possível que, durante a cópia, algum arquivo tenha sido recriado de forma menos esparsa, substituindo trechos esparsos por zeros "reais". Para usar o arquivo esparso,
rsync
você tinha que usar a-S
opção.Quando vi diferenças como essa no passado, geralmente era devido a uma diferença no tamanho do bloco das unidades. Isso é especialmente verdadeiro se a unidade original for mais antiga. Você pode verificar isso com o seguinte.
Suas opções de rsync não copiarão hardlinks, tente adicionar
-H
Arquivos esparsos, como imagens de VM, também podem aumentar o uso ao substituir vazios por blocos reais. Tente usar
--sparse
a opção com rsync.Você também pode tentar usar
diff
para comparar as árvores de diretórios. Consulte https://stackoverflow.com/questions/4997693/given-two-directory-trees-how-can-i-find-out-which-files-differ