Como usar o RSYNC para obter arquivos inalterados com hard-link e arquivos anexados copiados localmente + acrescentados?

5

Estou tentando descobrir uma maneira de usar o rsync (uma ou mais vezes) e possivelmente outros comandos (como cp -lr) para realizar o seguinte:

  1. Sincronize a pasta remota A com a pasta local B
  2. Eu já tenho uma pasta local C que é uma sincronização anterior de A
  3. Eu quero que os arquivos que estão inalterados entre C e A sejam criados em B como um link físico
  4. Desejo que novos arquivos em A sejam transferidos de volta para B
  5. Eu quero arquivos que tenham sido excluídos em A, sem link físico em B ou com link físico e depois excluídos.
  6. Eu quero arquivos que foram modificados (anexando dados) em A copiado localmente de C para B e ter apenas os bytes anexados transferidos e anexados à nova cópia.

Algumas restrições que sei serem verdadeiras que podem ajudar a encontrar uma solução:

  • Existem dois tipos de arquivos em A:
    1. Imutáveis, que são criados novos ou excluídos.
    2. Os mutáveis, que são sempre modificados ao anexar dados, e também podem ser excluídos.
  • Esses dois tipos de arquivos podem ser facilmente distinguidos, pois cada grupo tem um prefixo fixo, portanto, qualquer comando pode segmentar um ou outro grupo ou ambos.

Minha solução atual é usar

rsync -av --link-dest C remote:A B

Mas isso tem a desvantagem de os arquivos anexados serem totalmente transferidos, aumentando o volume em mais de 10X.

Quaisquer melhorias em relação a esta solução são bem-vindas, e ainda melhor se todas as transferências forem feitas com o rsync.

NOTA: não há problema em usar várias rodadas de rsync para alcançá-lo, a falta de atomicidade nesse sentido não é um problema, desde que C não seja alterado.

    
por Santi P. 15.07.2011 / 20:11

1 resposta

1

Bem, eu não achava que conseguiria fazer isso até que descobri recentemente um truque bacana que você pode fazer com o rsync e, como ninguém respondeu em algum momento, apresentarei minha solução.

O truque é quando você usa os seguintes argumentos:

rsync --suffix "" --backup-dir "." ...

Isso faz com que o rsync faça backup de arquivos antes de modificá-los, mas os backups acabam sendo in-loco, então você está realmente fazendo cópias dos arquivos antes de modificá-los. Isso permite que você altere os arquivos com link físico sem alterar os originais.

Então, a sequência para realizar o comportamento desejado pode ser a seguinte:

# locally hard-link the mutable files
rsync -ahv --link-dest C --include-from MUTABLE_FILES.filter C/* B

# copy locally + append remotely changed files 
# (also delete mutable files that disappeared at remote location A)
rsync -ahbv --suffix "" --backup-dir "." --append-verify \
      --include-from MUTABLE_FILES.filter --delete A/* B 

# now hard-link locally + transfer immutable files
rsync -ahv --link-dest C --include-from IMMUTABLE_FILES.filter A/* B

Isso provavelmente poderia ser resolvido com as duas primeiras etapas sem usar filtros, mas no meu caso de uso particular para garantir a coerência no destino final eu preciso dos arquivos mutáveis transferidos antes dos imutáveis, e a ordenação alfabética padrão feita pelo rsync não garanto isso no meu caso. A razão pela qual eu preciso disso é que os arquivos mutáveis podem ser excluídos e substituídos por um arquivo imutável. Se eu não transferi o arquivo imutável porque ele não existia no momento, mas o mutável desaparece antes de eu chegar nele, não tenho nenhum dos dois e perco os dados.

    
por 20.07.2011 / 23:39