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élite, substituindo essas duplicatas por hardlinks. O administrador do repositório de origem não quer ou não pode fazer isso na fonte, então estou tentando fazer isso após o fato no servidor de distribuição. Eu criei um script bash simples baseado no fdupes
comando que encontra grupos de duplicatas e os substitui por hardlinks para um único arquivo. As transferências rsync para os servidores satélite preservam esses hardlinks conforme desejado, graças à opção -H. A transferência do repositório de origem, entretanto, 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á existam 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?
Responder1
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 vinculados ao destino. Se um dos arquivos (ou ambos) acabar sendo retransmitido, o hard link no destino será quebrado, caso contrário, permanecerá intacto. Ou seja, mesmo com a --hard-links
opção, rsync
não quebrará um hardlink no destino só porque os arquivos não estão hardlinked na origem.
Os critérios para retransmitir um arquivo dependem das opções --checksum
( -c
) e --ignore-times
( -I
).
- Se a opção
--checksum
for fornecida, apenas os arquivos que diferem em tamanho ou soma de verificação entre origem e destino serão retransmitidos. Conseqüentemente, se o conteúdo do arquivo não tiver sido alterado, um link físico no destino será preservado, mesmo que não exista na origem. - Se a opção
--ignore-times
for dada, todos os arquivos serão retransmitidos, quebrando qualquer link físico no destino que não exista na origem. - Se nenhuma dessas duas opções for fornecida,
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 e 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 e hora poderá corresponder.
Responder2
Ele preserva os links físicos de origem se você usar a opção -H ou --hard-links
Aquilo vainãocrie links físicos - você terá que fazer isso após procurar arquivos com a mesma soma de verificação, excluir um e adicionar um link físico para substituí-lo. Afinal, você não gostaria que o rsync transformasse cada arquivo de conteúdo duplicado em um link físico para o mesmo arquivo. Imagine se cada arquivo de comprimento 0 fosse um link físico - você adiciona conteúdo a um e altera o conteúdo de todos.