Cómo convertir archivos gz (gzip) existentes a rsyncable

12

Estoy usando rsync para hacer una copia de seguridad de un repositorio que contiene muchos archivos gz, incluidos muchos nuevos cada día. La copia de seguridad de rsync avanza más lentamente de lo debido porque estos archivos gz no están construidos con la opción --rsyncable de gzip (que hace que los archivos gz sean mucho más amigables para rsync sin aumentar significativamente su tamaño o afectar su compatibilidad). Y no puedo solucionar el problema en el momento de la creación porque los archivos son generados por un script de python (rdiff-backup) que usa el módulo gzip de python y esto no admite un equivalente al grsip --rsyncable.

Entonces, antes de ejecutar rsync, puedo identificar cualquier archivo gz nuevo en los datos de origen (es decir, nuevo desde la última vez que se ejecutó rsync). Ahora quiero 'volver a comprimir' estos archivos para que estén comprimidos en formato rsyncable. Entonces puedo ejecutar rsync desde la fuente optimizada.

Creo que esto significa ejecutar cada archivo a través de gunzip y luego gzip --rsyncable, pero no estoy muy seguro de cómo hacerlo de una manera que no corra el riesgo de perder datos o metadatos. Sugerencias recibidas con gratitud.

gogoud
fuente
8
La única forma que --rsyncabledebería importar es si los archivos se cambian entre ejecuciones e rsyncintenta enviar los cambios. A los archivos nuevos no les importa si son rsyncable o no, porque rsyncde todos modos tiene que enviar todos los datos. ¿Se están cambiando los archivos entre las ejecuciones de rsync?
Tom Hunt
Buen punto. En realidad no estoy seguro, lo comprobaré. Supongamos por ahora que sí, el contenido de algunos archivos gz cambia.
gogoud
Lo mejor que se me ocurre es ejecutar un script que busque nuevos archivos, descomprimirlos y luego volver a comprimirlos --rsyncable.
Tom Hunt
Estoy de acuerdo en que si los archivos no cambian, esto no debería ser un problema. En particular, para la velocidad, asegúrese de omitir la suma de comprobación en función del tiempo al preservar los tiempos utilizando la -abandera. Además, mi versión de gzip no tiene un --rsyncableindicador, pero viene con un programa llamado znewque probablemente podría usarse para lo que necesita.
user3188445
2
Resulta que, como pensó Tom, los archivos gz creados por rdiff-backup no cambian una vez creados, por lo que usarlos --rsyncableno ayudaría. Esperaba una línea de código o script corto que descomprimiera de forma segura un archivo gz y lo volviera a empaquetar usando --rsyncable. Pero es solo una pregunta académica para mí ahora.
gogoud

Respuestas:

1
#! /bin/bash

set -euo pipefail

##  TOKEN's creation time marks the time since last recompression
TOKEN=.lastRecompression   

if [ -f ${TOKEN} ]
then
    find -name '*.gz' -cnewer "${TOKEN}"
else
    # Process all compressed files if there is no token.
    find -name '*.gz'
fi | while read f
do
    # Do it in two steps
    gunzip < "$f" | gzip --rsyncable > "$f.tmp"

    # Preserve attributes
    cp "$f" "$f.tmp" --attributes-only

    # and rename atomically.
    # set -e ensures that a problem in the previous step 
    # will stop the full script. 
    mv -v "$f.tmp" "$f"
done

# Update the token
touch ${TOKEN}
Raúl Salinas-Monteagudo
fuente
1
Al hacerlo gunzip | gzip, está perdiendo el nombre y la hora sin comprimir almacenados en el archivo gz (y visto con gzip -vNl)
Stéphane Chazelas
@ Stéphane Chazelas: Tiene razón: si esta información es relevante (nunca ha sido relevante para mí), la estamos perdiendo. Quizás la mejor solución sería que gunzip soporte directamente esta compresión. Podría pasar todos los metadatos internamente.
Raúl Salinas-Monteagudo
@ StéphaneChazelas ¿Conoces alguno para hacerlo sin pérdidas?
Tom Hale