como fazer com que o rsync vincule arquivos idênticos à opção --link-dest se um arquivo antigo já existir?

11

Pode-se pensar que --link-destum arquivo idêntico funcionaria em todos os casos. Mas isso não ocorre quando o arquivo existe, mesmo que esteja desatualizado / com conteúdo diferente.

É por isso, na página de manual do rsync --link-dest:

"Esta opção funciona melhor ao copiar para uma hierarquia de destino vazia, pois o rsync trata os arquivos existentes como definitivos (para que o rsync nunca procure nos diretórios de destino do link quando um arquivo de destino já existe )"

Isso significa que, se y/fileexistir o mesmo que a fonte e z/fileestiver desatualizado,

rsync -a --del -link-dest=y source:/file z

resultará na utilização de DOIS inodes (e duas vezes o espaço em disco) y/filee z/file, que terão o mesmo conteúdo e carimbos de dados.

Me deparei com isso porque faço backups diários basicamente com esse script executado uma vez por dia:

mv $somedaysago $today; 
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today

Como meus backups abrangem até 10 milhões de arquivos, a execução rm -rf $olddir; rsync source:$dir newdirlevaria muito tempo (especialmente quando apenas 0,5% dos arquivos são alterados por dia, incorrendo na exclusão e criação de entradas de 10 milhões de diretórios apenas para lidar com 50 mil arquivos novos ou alterados, o que tornaria meu backups não concluídos a tempo para o dia seguinte).

Aqui está uma demonstração da situação:

aé a nossa fonte, 1através de 4nossos backups numerados:

$ mkdir -p 1 2; echo foo > 1/foobar; cp -lrv 1/* 2
`1/foobar' -> `2/foobar'
$ ls -i1 */foobar
1053003 1/foobar
1053003 2/foobar

$ mkdir a; echo quux > a/foobar
$ mv 1 3; rsync -avPhyH --del --link-dest=../2 a/ 3
sending incremental file list
./
foobar
           5 100%    0.00kB/s    0:00:00 (xfer#1, to-check=0/2)

sent 105 bytes  received 34 bytes  278.00 bytes/sec
total size is 5  speedup is 0.04

$ ls -i1 */foobar
1053003 2/foobar
1053007 3/foobar
1053006 a/foobar

$ mv 2 4; rsync -avPhyH --del --link-dest=../3 a/ 4
sending incremental file list
./
foobar
           5 100%    0.00kB/s    0:00:00 (xfer#1, to-check=0/2)

sent 105 bytes  received 34 bytes  278.00 bytes/sec
total size is 5  speedup is 0.04


$ ls -il1 */foobar
1053007 -rw-r--r-- 1 math math 5 Mar 30 00:57 3/foobar
1053008 -rw-r--r-- 1 math math 5 Mar 30 00:57 4/foobar
1053006 -rw-r--r-- 1 math math 5 Mar 30 00:57 a/foobar

$ md5sum [34a]/foobar
d3b07a382ec010c01889250fce66fb13  3/foobar
d3b07a382ec010c01889250fce66fb13  4/foobar
d3b07a382ec010c01889250fce66fb13  a/foobar

Agora, temos dois backups a/foobaridênticos em todos os aspectos, incluindo carimbo de data e hora, mas ocupando inodes diferentes.

Pode-se pensar que seria uma solução --delete-before, que mata os benefícios da varredura incremental, mas isso não ajuda, pois o arquivo não será excluído, mas usado como base no caso de uma cópia incremental ser possível.

Pode-se supor ainda mais, então podemos desativar esse hedge de cópia incremental --whole-file, mas isso não ajuda o algoritmo, não há como obter o que queremos.

Considero esse comportamento outro bug no rsync, onde um comportamento benéfico pode ser interpretado a partir de seleções cuidadosas de vários argumentos de comando, mas o resultado desejado não está disponível.

Infelizmente, uma solução seria passar de um único rsync como uma operação atômica para uma execução a seco -n, registrando-a, processando esse log como entrada para pré-excluir manualmente todos os arquivos alterados e executando rsync --link-destpara obter o que queremos - um grande argumento comparado a um único rsync limpo.

Adendo: tentou pré-vincular $yesterdaye $todayno servidor de backup antes do backup às caixas de produção com rsync --link-dest=../$yesterday $yesterday/ $today- mas o mesmo resultado - qualquer arquivo que exista de qualquer forma, mesmo com 0 comprimento, nunca será removido e será destinado ao link, em vez de um todo uma nova cópia será feita a partir do fornecedor com um novo inode e utilizando mais espaço em disco.

Considerada pax(1)uma possível solução de pré-vinculação antes do backup.

matemática
fonte
Eu uso --delete-afterneste cenário de uso, o que há de errado nisso?
gogoud
1
--delete-afterestá bem, mas não está relacionado ao problema em questão. Os arquivos ausentes da fonte serão excluídos após a conclusão da cópia. O problema que estou elucidando refere-se a um backup que está sendo feito hoje, idêntico ao de ontem, mas contra um arquivo desatualizado existente antigo, que não está vinculado ao inode de ontem, mas armazenado como um novo arquivo com o dobro do espaço total em disco do dia anterior. cópia idêntica é considerada.
matemática
Não tenho certeza do que você pergunta. Você já considerou rsnapshot? Além disso, considere escrever um pequeno script para vincular novamente arquivos "idênticos". Eu faço as duas coisas nos meus sistemas.
roaima
1
Se você não obtiver a resposta que precisa aqui, poderá postar na lista rsync. Os desenvolvedores do rsync respondem regularmente a perguntas, junto com muitos usuários avançados. Você pode encontrá-los em lists.samba.org/mailman/listinfo/rsync . Espreito principalmente por lá e aprendo muito.
Joe
O rsnapshot não reciclará backups antigos - e eu preciso: se eu tiver backups de 2 e 2 meses + 1 dia, posso alternar um como o novo destino. Como ~ 5% dos arquivos são alterados / dia, eu crio 50K hardlinks em vez de 10M. Esse diferencial de velocidade permite fazer backup de 5 servidores / noite versus não. hardlink(1)é lento (15x mais lento que a verificação de metadados do rsync); paxé mais rápido, mas supera as cabeças dos discos rígidos, comparando o backup antigo com o novo. rsync -nobter a lista delta significa atingir os servidores de produção duas vezes (a digitalização de 10 milhões de arquivos é muito mais impactante do que copiar as alterações de 50 mil). Enviarei a lista por e-mail sobre uma opção no rsync para permitir isso.
math

Respostas:

12

(Convertido da edição da pergunta)

Isso é resolvido com a atualização do rsync. A versão 3.1.1 ou posterior agora substituirá arquivos idênticos no destino e --link-destdiretório por um arquivo com link físico. Economiza muito espaço.

Michael Mrozek
fonte