Comment convertir des fichiers gz (gzip) existants en rsyncable

12

J'utilise rsync pour sauvegarder un référentiel qui contient de nombreux fichiers gz, dont de nombreux nouveaux chaque jour. La sauvegarde rsync se déroule plus lentement qu'elle ne le devrait car ces fichiers gz ne sont pas construits avec l'option --rsyncable de gzip (ce qui rend les fichiers gz beaucoup plus «conviviaux pour rsync» sans augmenter significativement leur taille ou affecter leur compatibilité). Et je ne peux pas résoudre le problème au moment de la création car les fichiers sont générés par un script python (rdiff-backup) qui utilise le module gzip de python et cela ne prend pas en charge un équivalent de --rsyncable de gzip.

Donc, avant d'exécuter rsync, je peux identifier tout nouveau fichier gz dans les données source (c'est-à-dire nouveau depuis la dernière exécution de rsync). Maintenant, je veux «re-gzip» ces fichiers afin qu'ils soient compressés au format rsyncable. Ensuite, je peux exécuter rsync à partir de la source optimisée.

Je pense que cela signifie exécuter chaque fichier via gunzip puis gzip --rsyncable, mais je ne sais pas trop comment le faire d'une manière qui ne risque pas de perdre des données ou des métadonnées. Suggestions reçues avec reconnaissance.

gogoud
la source
8
La seule façon --rsyncabledevrait être de savoir si les fichiers sont modifiés entre les exécutions et rsynctente d'envoyer les modifications. Les nouveaux fichiers ne se soucient pas s'ils sont synchronisables ou non, car ils rsyncdoivent quand même envoyer toutes les données. Les fichiers sont-ils modifiés entre les exécutions rsync?
Tom Hunt
Bon point. En fait, je ne suis pas sûr, je vais vérifier cela. Supposons pour l'instant que oui, le contenu de certains fichiers gz soit modifié.
gogoud
La meilleure chose à laquelle je peux penser est d'exécuter un script qui vérifie les nouveaux fichiers, les décompresse, puis les recompose avec --rsyncable.
Tom Hunt
Je suis d'accord que si les fichiers ne changent pas, cela ne devrait pas être un problème. En particulier, pour la vitesse, assurez-vous d'ignorer la somme de contrôle en fonction du temps en préservant les temps à l'aide du -adrapeau. De plus, ma version de gzip n'a pas d' --rsyncableindicateur, mais elle est livrée avec un programme appelé znewqui pourrait probablement être utilisé pour ce dont vous avez besoin.
user3188445
2
Il s'avère que, comme le pensait Tom, les fichiers gz créés par rdiff-backup ne changent pas une fois créés et donc l'utilisation --rsyncablen'aiderait pas. J'espérais une ligne de code ou un script court qui déballerait en toute sécurité une archive gz et la reconditionnerait en utilisant --rsyncable. Mais c'est juste une question académique pour moi maintenant.
gogoud

Réponses:

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
la source
1
Ce faisant gunzip | gzip, vous perdez le nom et l'heure non compressés tels qu'ils sont stockés dans le fichier gz (et vus avec gzip -vNl)
Stéphane Chazelas
@ Stéphane Chazelas: Vous avez raison: si ces informations sont pertinentes (elles n'ont jamais été pertinentes pour moi), nous les perdons. La meilleure solution serait peut-être que gunzip supporte directement cette recompression. Il pourrait transmettre toutes les métadonnées en interne.
Raúl Salinas-Monteagudo
@ StéphaneChazelas Connaissez-vous quelqu'un pour le faire sans perte?
Tom Hale