Estou executando um servidor rsync (baseado em Linux) para distribuição de software. Um servidor de repositório de origem (baseado em Windows) que está fora do meu controle envia pacotes de software para ele via rsync, e cerca de cem servidores satélites em todo o mundo extraem dele, também via rsync.
O repositório de origem contém muitos arquivos duplicados grandes. Quero reduzir o espaço em disco e o consumo de largura de banda nos servidores satélites, substituindo essas duplicatas por hardlinks. O administrador do repositório de origem não quer ou não pode fazê-lo na origem, então estou tentando fazer isso após o fato no servidor de distribuição. Eu criei um script bash simples baseado nofdupes
comando que encontra grupos de duplicatas e os substitui por hardlinks para um único arquivo. As transferências rsync para os servidores satélites preservam esses hardlinks conforme desejado graças à opção -H. A transferência do repositório de origem, no entanto, produz resultados inconsistentes. Às vezes, a desduplicação é preservada. Às vezes, o servidor de origem retransmite todos os arquivos de um grupo desduplicado e a desduplicação é interrompida, mesmo que os arquivos de origem não tenham sido alterados.
Daí a minha pergunta: Qual é o comportamento oficial do rsync caso seja solicitado a sincronizar dois arquivos idênticos, mas separados e os arquivos já existirem no destino com o conteúdo correto, mas como hardlinks para o mesmo arquivo? Qual é o critério exato para retransmitir um arquivo? Existe uma maneira de garantir que o hardlink no destino seja preservado nessa situação, mesmo que o hardlink não exista na origem?
tl;dr: Para preservar a desduplicação em nível de arquivo por meio de links físicos no destino, execute
rsync
com a--checksum
opção.Resposta completa, de acordo com uma série de experimentos que fiz:
Se dois arquivos não estiverem vinculados na origem,
rsync
sincronizará cada um deles individualmente com o destino. Não importa se os arquivos estão com hardlink no destino. Se um dos arquivos (ou ambos) for retransmitido, o link físico no destino será quebrado, caso contrário, ele permanecerá intacto. Ou seja, mesmo com a--hard-links
opção,rsync
não vai quebrar um hardlink no destino só porque os arquivos não estão hardlinked na origem.Os critérios para retransmissão de um arquivo dependem das opções
--checksum
(-c
) e--ignore-times
(-I
).--checksum
for fornecida, apenas os arquivos que diferem em tamanho ou soma de verificação entre origem e destino são retransmitidos. Conseqüentemente, se o conteúdo do arquivo não for alterado, um link físico no destino será preservado, mesmo que não exista na origem.--ignore-times
for fornecida, todos os arquivos serão retransmitidos, quebrando qualquer link físico no destino que não exista na origem.rsync
usará os carimbos de data e hora de modificação dos arquivos de origem e destino para sua decisão. Nesse caso, se os carimbos de data/hora dos dois arquivos de origem forem diferentes, um link físico no destino sempre será quebrado porque apenas um dos dois carimbos de data/hora pode corresponder.Ele preserva os links físicos de origem se você usar a opção -H ou --hard-links
Isso não criará links físicos - você terá que fazer isso após o fato procurando arquivos com a mesma soma de verificação, excluindo um e adicionando um link físico para substituí-lo. Afinal, você não gostaria que o rsync transformasse cada arquivo duplicado de conteúdo em um link físico para o mesmo arquivo. Imagine se cada arquivo de tamanho 0 fosse um link físico -- você adiciona conteúdo a um, você altera o conteúdo para todos.