Blog Arripio

Rsync não faz análise de checksum dos arquivos por padrão

Rsync não faz análise de checksum dos arquivos por padrão

Do man rsync

       Rsync  finds  files  that  need to be transferred using a “quick check” algorithm (by default) that looks for files

       that have changed in size or in last-modified time.  Any changes in the other preserved attributes (as requested by

       options)  are  made  on  the destination file directly when the quick check indicates that the file’s data does not

       need to be updated.

Logo, se temos dois arquivos:

mkdir -p /tmp/testersync/{origem,destino}

echo “O rsync nao faz checksum por padrao” > /tmp/testersync/origem/arquivo

Se, um tempo depois, você criar um arquivo igual no destino:

echo “O rsync nao faz checksum por padrao” > /tmp/testersync/destino/arquivo

E usar o rsync:

rsync -avi /tmp/testersync/origem/ /tmp/testersync/destino

sending incremental file list

>f..t…… arquivo

Esse t na saída do log mostra que ele notou que o timestamp está diferente.

Se você mudar o tamanho da frase:

echo “Claro que o rsync faz checksum por padrao, oras” > /tmp/testersync/destino/arquivo

Agora o rsync vai falar que ele mudou não só o timestamp mas o tamanho:

rsync -avi  /tmp/testersync/origem/ /tmp/testersync/destino

sending incremental file list

>f.st…… arquivo

Agora vamos tentar enganar o rsync. Vou criar o arquivo com a mesma frase, mas toda em maiúscula:

      cat /tmp/testersync/origem/arquivo | tr ‘[a-z]’ ‘[A-Z]’ > /tmp/testersync/destino/arquivo

Do ponto de vista computacional, claramente eles são diferentes:

find /tmp/testersync -type f -exec sha256sum ‘{}’ \+

f27d88d52759a4b07c077f34c230c47b94ea88b6640fc47b44d562243966eb7e  /tmp/testersync/destino/arquivo

47c6ec4243572212a13d657637a62975a1007cf5881668cf7d02d370956dc3b3  /tmp/testersync/origem/arquivo

O tamanho é o mesmo:

find /tmp/testersync -type f -printf ‘%P: %s\n’

destino/arquivo: 36

origem/arquivo: 36

Mas se você usar o rsync, ele vai retransferir o arquivo porque o mtime é diferente, e isso é um grande indicador que algo mudou no arquivo:

find /tmp/testersync -type f -printf ‘%P: %t\n’

destino/arquivo: Sun Dec 17 14:45:20.4011998470 2023

origem/arquivo: Sun Dec 17 14:43:11.4812008470 2023

Então, se você executar o rsync, ele vai substituir o arquivo:

 rsync -avi /tmp/testersync/origem/ /tmp/testersync/destino

sending incremental file list

>f..t…… arquivo

find /tmp/testersync -type f -exec sha256sum ‘{}’ \+

47c6ec4243572212a13d657637a62975a1007cf5881668cf7d02d370956dc3b3  /tmp/testersync/destino/arquivo

47c6ec4243572212a13d657637a62975a1007cf5881668cf7d02d370956dc3b3  /tmp/testersync/origem/arquivo

Só que isso é bem diferente de executar análise de checksum, que em larga escala, pode ser muito ineficiente. 

Vamos enganar o rsync. Primeiro recrio o arquivo diferente:

      cat /tmp/testersync/origem/arquivo | tr ‘[a-z]’ ‘[A-Z]’ > /tmp/testersync/destino/arquivo


Depois eu altero os horários dele para ficarem iguais ao da origem (conhece essa função do comando touch?):

touch /tmp/testersync/destino/arquivo -r /tmp/testersync/origem/arquivo

Como o rsync enxerga o arquivo agora?

find /tmp/testersync -type f -printf ‘%P:Tamanho %s, Mtime %t\n’

destino/arquivo:Tamanho 36, Mtime Sun Dec 17 14:43:11.4812008470 2023

origem/arquivo:Tamanho 36, Mtime Sun Dec 17 14:43:11.4812008470 2023

Do ponto de vista do rsync, eles agora são iguais:

rsync -avi /tmp/testersync/origem/ /tmp/testersync/destino

sending incremental file list

sent 85 bytes  received 12 bytes  194.00 bytes/sec

total size is 36  speedup is 0.37

Pelo log, você pode ver que ele não transferiu nada, e o checksum segue diferente:

find /tmp/testersync -type f -exec sha256sum ‘{}’ \+

f27d88d52759a4b07c077f34c230c47b94ea88b6640fc47b44d562243966eb7e  /tmp/testersync/destino/arquivo

47c6ec4243572212a13d657637a62975a1007cf5881668cf7d02d370956dc3b3  /tmp/testersync/origem/arquivo

Neste tipo de situação – que geralmente é improvável de acontecer, mas não necessariamente impossível, você precisa da flag -c:

rsync -avic /tmp/testersync/origem/ /tmp/testersync/destino

sending incremental file list

>fc…….. arquivo

find /tmp/testersync -type f -exec sha256sum ‘{}’ \+

47c6ec4243572212a13d657637a62975a1007cf5881668cf7d02d370956dc3b3  /tmp/testersync/destino/arquivo

47c6ec4243572212a13d657637a62975a1007cf5881668cf7d02d370956dc3b3  /tmp/testersync/origem/arquivo

Se você quiser garantir que a origem e o destino são iguais, você precisa desta flag. Se você está trabalhando com arquivos que usam algum tipo de empacotamento binário de data (basicamente qualquer coisa), a chance desse tipo de situação passar batido é extremamente baixa. Mas quando você trabalha com muitos arquivos textos com formatos e layouts parecidos e com filesystems extravagantes que podem não expor o mtime adequadamente, você pode cair nessa armadilha.

Autor: Marcelo Rocha

Leave a Comment

O seu endereço de email não será publicado.