Si potrebbe pensare che --link-dest
lavorare su un file identico funzionerebbe in tutti i casi. Ma non lo è quando il file esiste, anche se il file non è aggiornato / ha contenuti diversi.
È per questo motivo, dalla pagina man di rsync su --link-dest
:
"Questa opzione funziona meglio quando si copia in una gerarchia di destinazione vuota, poiché rsync considera i file esistenti come definitivi (quindi rsync non cerca mai nelle directory dir-link quando esiste già un file di destinazione )"
Ciò significa che se y/file
esiste come l'origine e non z/file
è aggiornato,
rsync -a --del -link-dest=y source:/file z
comporterà DUE inode (e il doppio dello spazio su disco) in uso, y/file
e z/file
, che avranno gli stessi contenuti e datastamp.
Mi sono imbattuto in questo perché eseguo backup giornalieri sostanzialmente con questo script eseguito una volta al giorno:
mv $somedaysago $today;
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today
Poiché i miei backup si estendono fino a 10 milioni di file, il processo rm -rf $olddir; rsync source:$dir newdir
richiederebbe troppo tempo (specialmente quando solo lo 0,5% dei file cambia al giorno, comportando la cancellazione e la creazione di voci dir 10M solo per gestire 50.000 file nuovi o modificati, il che renderebbe il mio backup non completati in tempo per il giorno successivo).
Ecco una demo della situazione:
a
è la nostra fonte, 1
attraverso 4
sono i nostri backup numerati:
$ 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
Ora abbiamo 2 backup a/foobar
che sono identici in tutti i modi, incluso il timestamp, ma che occupano diversi inode.
Si potrebbe pensare che sarebbe una soluzione --delete-before
, che uccide il vantaggio della scansione incrementale, ma ciò non aiuta neanche perché il file non verrà eliminato, ma utilizzato come base nel caso in cui sia possibile una copia incrementale.
Si potrebbe ulteriormente supporre che possiamo disattivare questa copertura con copia incrementale --whole-file
, ma ciò non aiuta l'algoritmo, non c'è modo di ottenere ciò che vogliamo.
Considero questo comportamento un altro bug in rsync, in cui un comportamento benefico potrebbe essere interpretato da accurate selezioni di vari argomenti di comando, ma il risultato desiderato non è disponibile.
Sfortunatamente una soluzione si sposterebbe da una singola rsync come operazione atomica a una versione a secco -n
, registrandola, elaborando quel registro come input per pre-cancellare manualmente tutti i file modificati, quindi eseguendo rsync --link-dest
per ottenere ciò che vogliamo - un grande kludge rispetto a un singolo rsync pulito.
Addendum: provato a precollegare $yesterday
e $today
sul server di backup prima del backup rispetto alle caselle di produzione con rsync --link-dest=../$yesterday $yesterday/ $today
- ma lo stesso risultato - qualsiasi file esistente in qualsiasi modo, anche a lunghezza 0, non verrà mai rimosso e linkestestato, anziché un intero la nuova copia verrà creata dal sorgente con un nuovo inode e utilizzando più spazio su disco.
Considerando pax(1)
come possibile soluzione pre-collegamento prima del backup.
--delete-after
va bene, ma non è correlato al problema in questione. I file mancanti dall'origine verranno eliminati al termine della copia. Il problema che sto chiarendo riguarda un backup fatto oggi che è identico a quello di ieri ma rispetto a un vecchio file obsoleto esistente che non è collegato all'inode di ieri, ma memorizzato come nuovo file al doppio dello spazio su disco totale di ieri copia identica è considerata.
rsnapshot
? Inoltre, considera di scrivere un piccolo script per ricollegare i file "identici". Faccio entrambi sui miei sistemi.
hardlink(1)
è lento (15 volte più lento della scansione dei metadati di rsync); pax
è più veloce ma blocca le testine HDD confrontando il vecchio backup con il nuovo. rsync -n
ottenere l'elenco delta significa colpire due volte i server di produzione (la scansione di file 10M ha un impatto molto maggiore rispetto alla copia delle modifiche da 50K). Invia l'elenco su un'opzione in rsync per consentirlo.
--delete-after
in questo scenario di utilizzo, cosa c'è di sbagliato in questo?