Uno podría pensar que --link-dest
trabajar en un archivo idéntico funcionaría en todos los casos. Pero no lo hace cuando el archivo existe, incluso si el archivo está desactualizado / tiene contenidos diferentes.
Es por esto, desde la página de manual de rsync en --link-dest
:
"Esta opción funciona mejor cuando se copia en una jerarquía de destino vacía, ya que rsync trata los archivos existentes como definitivos (por lo que rsync nunca se ve en los directorios link-dest cuando ya existe un archivo de destino )"
Esto significa que si y/file
existe igual que la fuente y z/file
está desactualizado,
rsync -a --del -link-dest=y source:/file z
dará como resultado que se utilicen DOS inodos (y el doble del espacio en disco) y/file
y z/file
que tendrán los mismos contenidos y marcas de fecha.
Me encontré con esto porque hago copias de seguridad diarias básicamente con este script ejecutado una vez al día:
mv $somedaysago $today;
yest=$today; today=`date +%Y%m%d`;
rsync -avPShyH --del --link-dest=../$yest host:/dirs $today
Debido a que mis copias de seguridad abarcan hasta 10 millones de archivos, rm -rf $olddir; rsync source:$dir newdir
tomaría demasiado tiempo (especialmente cuando solo el 0.5% de los archivos cambian por día, incurriendo en la eliminación y creación de entradas de directorio de 10 millones solo para manejar 50 mil archivos nuevos o modificados, lo que haría que mi copias de seguridad no completadas a tiempo para el día siguiente).
Aquí hay una demostración de la situación:
a
es nuestra fuente, a 1
través de 4
nuestras copias de seguridad numeradas:
$ 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
Ahora tenemos 2 copias de seguridad a/foobar
que son idénticas en todos los sentidos, incluida la marca de tiempo, pero que ocupan inodos diferentes.
Uno podría pensar que sería una solución --delete-before
, que mata el beneficio del escaneo incremental, pero esto tampoco ayuda, ya que el archivo no se eliminará, sino que se usará como base en caso de que sea posible una copia incremental.
Se podría suponer que podríamos desactivar esta cobertura de copia incremental --whole-file
, pero esto no ayuda al algoritmo, no hay forma de obtener lo que queremos.
Considero que este comportamiento es otro error en rsync, donde un comportamiento beneficioso podría interpretarse a partir de selecciones cuidadosas de varios argumentos de comando, pero el resultado deseado no está disponible.
Desafortunadamente, una solución sería pasar de una única rsync como una operación atómica a una ejecución en seco con -n
, iniciar sesión, procesar ese registro como entrada para eliminar previamente manualmente todos los archivos modificados, y luego ejecutar rsync --link-dest
para obtener lo que queremos: un gran error en comparación con un solo rsync limpio.
Anexo: intentó preenlazar $yesterday
y $today
en el servidor de copia de seguridad antes de la copia de seguridad en cajas de producción con rsync --link-dest=../$yesterday $yesterday/ $today
, pero el mismo resultado, cualquier archivo que exista de alguna manera, incluso 0 de longitud, nunca se eliminará y se desestimulará el enlace, en su lugar Se realizará una nueva copia del origen con un nuevo inodo y utilizando más espacio en disco.
Mirando pax(1)
como una posible solución de pre-enlace-antes-copia de seguridad.
--delete-after
está bien, pero no está relacionado con el problema en cuestión. Los archivos que faltan en la fuente se eliminarán después de que se realice la copia. El problema que estoy aclarando se relaciona con una copia de seguridad que se está haciendo hoy que es idéntica a la de ayer pero contra un archivo obsoleto existente que no está vinculado al inodo de ayer, pero se almacena como un archivo nuevo al doble del espacio total en disco cuando ayer Se considera copia idéntica.
rsnapshot
? Además, considere escribir un pequeño script para volver a vincular archivos "idénticos". Hago ambas cosas en mis sistemas.
hardlink(1)
es lento (15 veces más lento que el escaneo de metadatos de rsync); pax
es más rápido pero agota los cabezales de HDD al comparar copias de seguridad antiguas con nuevas. rsync -n
obtener la lista delta significa llegar a los servidores de producción dos veces (escanear archivos de 10M tiene mucho más impacto que copiar los cambios de 50K). Enviaré la lista por correo sobre una opción en rsync para permitir esto.
--delete-after
en este escenario de uso, ¿qué hay de malo en esto?