O rsync pode retomar depois de ser interrompido?

188

Eu costumava rsynccopiar um grande número de arquivos, mas meu sistema operacional (Ubuntu) reiniciou inesperadamente.

Após a reinicialização, corri rsyncnovamente, mas a partir da saída no terminal, descobri que rsyncainda havia copiado os que já haviam sido copiados anteriormente. Mas ouvi dizer que rsyncé capaz de encontrar diferenças entre origem e destino e, portanto, apenas copiar as diferenças. Então, eu me pergunto no meu caso se rsyncpode retomar o que restou da última vez?

Tim
fonte
Sim, o rsync não copiará novamente os arquivos que já foram copiados. Existem alguns casos extremos em que sua detecção pode falhar. Ele copiou todos os arquivos já copiados? Quais opções você usou? Quais eram os sistemas de arquivos de origem e de destino? Se você executar o rsync novamente depois de ter copiado tudo, ele será copiado novamente?
Gilles
@ Gilles: Obrigado! (1) Acho que vi o rsync copiando os mesmos arquivos novamente de sua saída no terminal. (2) As opções são as mesmas do meu outro post, ie sudo rsync -azvv /home/path/folder1/ /home/path/folder2. (3) A origem e o destino são NTFS, a fonte de compra é um disco rígido externo e o destino é um disco rígido interno. (3) Agora está em execução e ainda não terminou.
Tim
Há também a bandeira --partial para retomar ficheiros parcialmente transferidos (útil para grandes arquivos)
jwbensley
3
@ Tim Em cima da minha cabeça, há pelo menos desvio do relógio e diferenças na resolução do tempo (um problema comum nos sistemas de arquivos FAT que armazenam os tempos em incrementos de 2 segundos, a --modify-windowopção ajuda nisso).
Gilles
1
se você não possui / ou /. no fim da cauda do argumento caminho de origem do arquivo, então ele estará fazendo uma cópia extra em um subdiretório que tem o mesmo nome que o diretório de origem
Skaperen

Respostas:

285

Primeiro, em relação à parte "resume" da sua pergunta, --partialapenas informa ao terminal de recebimento que mantenha os arquivos parcialmente transferidos se o terminal de envio desaparecer como se tivesse sido completamente transferido.

Durante a transferência de arquivos, eles são salvos temporariamente como arquivos ocultos em suas pastas de destino (por exemplo .TheFileYouAreSending.lRWzDC) ou em uma pasta escolhida especificamente se você definir a --partial-diropção. Quando uma transferência falha e --partialnão está definida, esse arquivo oculto permanecerá na pasta de destino com esse nome criptográfico, mas, se --partialestiver definido, o arquivo será renomeado para o nome real do arquivo de destino (nesse caso TheFileYouAreSending), mesmo que o arquivo não está completo. O ponto é que você pode concluir a transferência posteriormente executando o rsync novamente com --appendou --append-verify.

Portanto, --partialele próprio não retoma uma transferência com falha ou cancelada. Para retomar, você precisará usar um dos sinalizadores acima mencionados na próxima execução. Portanto, se você precisar garantir que o destino nunca contenha arquivos que parecem estar bem, mas estão incompletos, não use --partial. Por outro lado, se você quiser ter certeza de que nunca deixa para trás arquivos com falha perdidos que estão ocultos no diretório de destino e sabe que poderá concluir a transferência posteriormente, --partialexiste para ajudá-lo.

No que diz respeito à --appendopção mencionada acima, esta é a opção "resumir" real, e você pode usá-la independentemente de também estar usando --partial. Na verdade, quando você está usando --append, nenhum arquivo temporário é criado. Os arquivos são gravados diretamente em seus destinos. Nesse sentido, --appendfornece o mesmo resultado que --partialem uma transferência com falha, mas sem criar esses arquivos temporários ocultos.

Portanto, para resumir, se você estiver movendo arquivos grandes e desejar a opção de retomar uma operação rsync cancelada ou com falha a partir do ponto exato em que rsyncparou, será necessário usar --appendou --append-verifyativar a próxima tentativa.

Como o @Alex aponta abaixo, desde a versão 3.0.0 rsyncagora existe uma nova opção --append-verify, que se comporta como --appendantes da troca. Você provavelmente sempre quer o comportamento de --append-verify, então verifique sua versão com rsync --version. Se você estiver em um Mac e não usando rsynca partir homebrew, você (pelo menos até e incluindo El Capitan) tem uma versão mais antiga e precisa usar --append, em vez de --append-verify. Por que eles não mantiveram o comportamento --appende, em vez disso, nomearam o recém --append-no-verify- chegado é um pouco intrigante. De qualquer maneira, --appenda rsyncversão anterior à 3 é igual --append-verifyà das versões mais recentes.

--append-verifynão é perigoso: ele sempre lê e compara os dados nas duas extremidades e não apenas assume que são iguais. Ele faz isso usando somas de verificação, para facilitar a rede, mas exige a leitura da quantidade compartilhada de dados nas duas extremidades da conexão antes que possa realmente retomar a transferência anexando ao destino.

Segundo, você disse que "ouviu dizer que o rsync é capaz de encontrar diferenças entre a origem e o destino e, portanto, apenas copiar as diferenças".

Está correto e é chamado de transferência delta, mas é uma coisa diferente. Para habilitar isso, você adiciona a opção -cou --checksum. Depois que essa opção é usada, o rsync examinará os arquivos existentes nas duas extremidades do fio. Ele faz isso em partes, compara as somas de verificação nas duas extremidades e, se elas diferem, transfere apenas as diferentes partes do arquivo. Mas, como @Jonathan aponta abaixo, a comparação é feita apenas quando os arquivos têm o mesmo tamanho nas duas extremidades - tamanhos diferentes farão com que o rsync carregue o arquivo inteiro, substituindo o destino com o mesmo nome.

Isso requer um pouco de computação nas duas extremidades inicialmente, mas pode ser extremamente eficiente na redução da carga de rede se, por exemplo, você estiver frequentemente fazendo backup de arquivos muito grandes, arquivos de tamanho fixo, que geralmente contêm pequenas alterações. Exemplos que vêm à mente são os arquivos de imagem de disco rígido virtual usados ​​em máquinas virtuais ou destinos iSCSI.

É notável que, se você usar --checksumpara transferir um lote de arquivos completamente novos para o sistema de destino, o rsync ainda calculará suas somas de verificação no sistema de origem antes de transferi-las. Porque eu não sei :)

Então, resumindo:

Se você está sempre usando rsync apenas "mover coisas de A para B" e querem a opção de cancelar essa operação e depois retomá-la, não usar --checksum, mas não utilizar --append-verify.

Se você estiver usando o rsync para fazer backup frequentemente, --append-verifyprovavelmente não fará muito por você, a menos que você tenha o hábito de enviar arquivos grandes que aumentam de tamanho continuamente, mas que raramente são modificados uma vez gravados. Como uma dica de bônus, se você estiver fazendo backup de um armazenamento compatível com snapshots como btrfsou zfs, adicionar a --inplaceopção ajudará a reduzir o tamanho dos snapshots, já que os arquivos alterados não são recriados, mas os blocos alterados são gravados diretamente sobre os antigos. Essa opção também é útil se você desejar evitar o rsync criar cópias de arquivos no destino quando ocorrerem apenas pequenas alterações.

Ao usar --append-verify, o rsync se comportará como sempre acontece em todos os arquivos do mesmo tamanho. Se diferirem na modificação ou em outros registros de data e hora, ele substituirá o destino pela fonte sem examinar esses arquivos ainda mais. --checksumcomparará o conteúdo (soma de verificação) de cada par de arquivos com nome e tamanho idênticos.

ATUALIZADO 01/09/2015 Alterado para refletir os pontos feitos por @Alex (obrigado!)

ATUALIZADO 14/07/2017 Alterado para refletir os pontos feitos por @Jonathan (obrigado!)

DanielSmedegaardBuus
fonte
4
Isto diz que --partialé suficiente.
Cees Timmerman
2
@CMCDragonkai Na verdade, confira a resposta de Alexander abaixo sobre --partial-dir- parece que é a bala perfeita para isso. Talvez eu tenha perdido alguma coisa inteiramente;)
DanielSmedegaardBuus
2
@DanielSmedegaardBuus Eu mesmo testei em uma conexão lenta, e é isso que vejo apenas --partial : o rsync copia o arquivo para o nome temporário, a conexão é interrompida, o rsync remoto eventualmente move o arquivo para o nome normal e fecha, depois fecha reexecutando com --partiale sem --append , o novo arquivo temporário é inicializado com uma cópia do arquivo remoto parcialmente transferido e a cópia continua de onde a conexão morreu. (Ubuntu 14.04 / rsync 3.1)
Izkata
4
Qual é o seu nível de confiança no comportamento descrito --checksum? De acordo com o documento man, tem mais a ver com a decisão de quais arquivos sinalizar para transferência do que com a transferência delta (que, presumivelmente, é rsynco comportamento padrão do site).
Jonathan Y.
56

TL; DR:

Basta especificar um diretório parcial, conforme recomendado pelas páginas de manual do rsync:

--partial-dir=.rsync-partial

Explicação mais longa:

Há realmente um recurso built-in para fazer isso usando a --partial-diropção, que tem várias vantagens sobre o --partiale --append-verify/ --appendalternativa.

Trecho das páginas de manual do rsync:

--partial-dir=DIR
      A  better way to keep partial files than the --partial option is
      to specify a DIR that will be used  to  hold  the  partial  data
      (instead  of  writing  it  out to the destination file).  On the
      next transfer, rsync will use a file found in this dir  as  data
      to  speed  up  the resumption of the transfer and then delete it
      after it has served its purpose.

      Note that if --whole-file is specified (or  implied),  any  par-
      tial-dir  file  that  is  found for a file that is being updated
      will simply be removed (since rsync  is  sending  files  without
      using rsync's delta-transfer algorithm).

      Rsync will create the DIR if it is missing (just the last dir --
      not the whole path).  This makes it easy to use a relative  path
      (such  as  "--partial-dir=.rsync-partial")  to have rsync create
      the partial-directory in the destination file's  directory  when
      needed,  and  then  remove  it  again  when  the partial file is
      deleted.

      If the partial-dir value is not an absolute path, rsync will add
      an  exclude rule at the end of all your existing excludes.  This
      will prevent the sending of any partial-dir files that may exist
      on the sending side, and will also prevent the untimely deletion
      of partial-dir items on the receiving  side.   An  example:  the
      above  --partial-dir  option would add the equivalent of "-f '-p
      .rsync-partial/'" at the end of any other filter rules.

Por padrão, o rsync usa um nome de arquivo temporário aleatório que é excluído quando uma transferência falha. Como mencionado, --partialvocê pode fazer com que o rsync mantenha o arquivo incompleto como se fosse transferido com êxito , para que seja possível anexá-lo posteriormente usando as opções --append-verify/ --append. No entanto, existem várias razões pelas quais isso é sub-ideal.

  1. Seus arquivos de backup podem não estar completos e, sem verificar o arquivo remoto que ainda deve estar inalterado, não há como saber.

  2. Se você está tentando usar --backupe --backup-diracabou de adicionar uma nova versão deste arquivo que nunca saiu antes no seu histórico de versões.

No entanto, se usarmos --partial-dir, o rsync preservará o arquivo parcial temporário e continuará o download usando esse arquivo parcial na próxima vez que você o executar, e não sofreremos os problemas acima.

Alexander O'Mara
fonte
38

Você pode adicionar a -Popção ao seu comando.

Na manpágina:

--partial By default, rsync will delete any partially transferred file if the transfer
         is interrupted. In some circumstances it is more desirable to keep partially
         transferred files. Using the --partial option tells rsync to keep the partial
         file which should make a subsequent transfer of the rest of the file much faster.

  -P     The -P option is equivalent to --partial --progress.   Its  pur-
         pose  is to make it much easier to specify these two options for
         a long transfer that may be interrupted.

Então, em vez de:

sudo rsync -azvv /home/path/folder1/ /home/path/folder2

Faz:

sudo rsync -azvvP /home/path/folder1/ /home/path/folder2

Obviamente, se você não quiser as atualizações de progresso, basta usar --partial, ou seja:

sudo rsync --partial -azvv /home/path/folder1/ /home/path/folder2
N2O
fonte
@ Flimm não está correto. Se houver uma interrupção (rede ou lado receptor), ao usar --partial, o arquivo parcial será mantido E será usado quando o rsync for reiniciado. Na página de manual: "Usar a opção --partial diz ao rsync para manter o arquivo parcial, o que deve <b> fazer uma transferência subsequente do restante do arquivo muito mais rápido </b>."
precisa saber é
2
@Flimm e @gaoithe, minha resposta não foi muito precisa e, definitivamente, não está atualizada. Eu o atualizei para refletir a versão 3 + do rsync. É importante ressaltar, no entanto, que --partialele próprio não retoma uma transferência com falha. Veja a minha resposta para mais detalhes :)
DanielSmedegaardBuus
2
@DanielSmedegaardBuus Eu tentei e o -Psuficiente no meu caso. Versões: o cliente possui 3.1.0 e o servidor 3.1.1. Interrompi a transferência de um único arquivo grande com ctrl-c. Acho que estou perdendo alguma coisa.
guettli
Por que vv? ou seja, vusado 2 vezes?
mrgloom 23/08
Onde o rsync salva parte do arquivo -azvvP?
mrgloom 23/08
1

Eu acho que você está ligando à força rsynce, portanto, todos os dados estão sendo baixados quando você se lembra novamente. use a --progressopção para copiar apenas os arquivos que não foram copiados e a --deleteopção para excluir os arquivos, se já tiverem sido copiados e agora ele não existe na pasta de origem ...

rsync -avz --progress --delete -e  /home/path/folder1/ /home/path/folder2

Se você estiver usando ssh para efetuar login em outro sistema e copiar os arquivos,

rsync -avz --progress --delete -e "ssh -o UserKnownHostsFile=/dev/null -o \
StrictHostKeyChecking=no" /home/path/folder1/ /home/path/folder2

deixe-me saber se há algum erro na minha compreensão deste conceito ...

Yadunandana
fonte
1
Você pode editar sua resposta e explicar o que sua chamada ssh especial faz e por que você aconselha isso?
precisa
2
@Fabien Ele diz ao rsync para definir duas opções ssh (o rsync usa ssh para conectar). O segundo diz ao ssh para não solicitar confirmação se o host ao qual ele está se conectando ainda não é conhecido (existindo no arquivo "hosts conhecidos"). O primeiro diz ao ssh para não usar o arquivo hosts conhecido padrão (que seria ~ / .ssh / known_hosts). Em vez disso, ele usa / dev / null, o que obviamente está sempre vazio, e como o ssh não encontraria o host lá, normalmente solicitaria confirmação, daí a opção dois. Após a ligação, ssh escreve o anfitrião agora conhecido por / dev / null, esquecendo-lo efetivamente instantaneamente :)
DanielSmedegaardBuus
1
... mas você provavelmente estava se perguntando que efeito, se houver, isso tem sobre a própria operação rsync. A resposta é nenhuma. Serve apenas para não ter o host ao qual você está se conectando adicionado ao seu arquivo de hosts conhecidos SSH. Talvez ele seja um administrador de sistemas, muitas vezes se conectando a um grande número de novos servidores, sistemas temporários ou outros enfeites. Não sei :)
DanielSmedegaardBuus
4
"use a opção --progress para copiar apenas os arquivos que não são copiados" O que?
moi
1
Existem alguns erros aqui; um é muito sério: --deleteexcluirá arquivos no destino que não existem na fonte. O menos sério é que --progressnão modifica como as coisas são copiadas; apenas fornece um relatório de progresso de cada arquivo que ele copia. (I corrigido o erro grave; substituiu-o com --remove-source-files.)
Paul d'Aoust
1

Eu estou usando esse script simples. Sinta-se à vontade para ajustar certos sinalizadores e / ou configurá-los.

#!/bin/bash

while [ 1 ]
do
    rsync -avz --partial [source] [dest]:
    if [ "$?" = "0" ] ; then
        echo "rsync completed normally"
        exit
    else
        echo "Rsync failure. Backing off and retrying..."
        sleep 180
    fi
done
NeverEndingQueue
fonte
1

Chegando tarde para isso, mas eu tinha a mesma pergunta e encontrei uma resposta diferente.

O --partialsinalizador ("manter arquivos parcialmente transferidos" rsync -h) é útil para arquivos grandes, como é --append("acrescenta dados a arquivos mais curtos"), mas a questão é sobre um grande número de arquivos.

Para evitar arquivos que já foram copiados, use -u(ou --update: "pule arquivos mais recentes no receptor").

lazysoundsystem
fonte