Jak przekonwertować istniejące pliki gz (gzip) na rsyncable


12

Korzystam z rsync do tworzenia kopii zapasowych repozytorium, które zawiera wiele plików GZ, w tym wiele nowych każdego dnia. Kopia zapasowa rsync przebiega wolniej niż powinna, ponieważ te pliki gz nie są budowane z opcją --rsyncable gzip (co czyni pliki gz bardziej „przyjaznymi dla rsync” bez znacznego zwiększenia ich rozmiaru lub wpływu na ich kompatybilność). I nie mogę rozwiązać problemu w czasie tworzenia, ponieważ pliki są generowane przez skrypt Pythona (rdiff-backup), który używa modułu gzip pythona, a to nie obsługuje odpowiednika - gsip - syncable.

Więc przed uruchomieniem rsync mogę zidentyfikować nowe pliki gz w danych źródłowych (tj. Nowe od ostatniego uruchomienia rsync). Teraz chcę ponownie „zgzipować” te pliki, aby były one zgzipowane w formacie rsyncable. Następnie mogę uruchomić rsync ze zoptymalizowanego źródła.

Myślę, że oznacza to uruchomienie każdego pliku przez gunzip, a następnie gzip --rsyncable, ale nie jestem zbyt pewien, jak to zrobić w sposób, który nie ryzykuje utraty danych lub metadanych. Sugestie otrzymane z wdzięcznością.


8
Jedyny sposób --rsyncablepowinien mieć znaczenie, jeśli pliki zostaną zmienione między uruchomieniami i rsyncspróbują wysłać zmiany. Nowe pliki nie dbają o to, czy można je synchronizować, czy nie, ponieważ i rsynctak muszą przesyłać wszystkie dane. Czy pliki są zmieniane między uruchomieniami rsync?
— Tom Hunt

Słuszna uwaga. Właściwie nie jestem pewien, sprawdzę to. Załóżmy na razie, że tak, zawartość niektórych plików gz ulega zmianie.
— gogoud

Najlepszą rzeczą, jaką mogę wymyślić, jest uruchomienie skryptu, który sprawdza nowe pliki, rozpakowuje je, a następnie ponownie zgzipuje --rsyncable.
— Tom Hunt

Zgadzam się, że jeśli pliki się nie zmienią, nie powinno to stanowić problemu. W szczególności, dla prędkości, pamiętaj o pomijaniu sum kontrolnych na podstawie czasu, zachowując czasy za pomocą -aflagi. Ponadto moja wersja gzip nie ma --rsyncableflagi, ale zawiera program o nazwie znew, który prawdopodobnie mógłby zostać użyty do tego, czego potrzebujesz.
— user3188445,

2
Okazuje się, że, jak pomyślał Tom, pliki gz utworzone przez rdiff-backup nie zmieniają się po utworzeniu, więc użycie --rsyncablenie pomogłoby. Miałem nadzieję na linię kodu lub krótki skrypt, który bezpiecznie rozpakowałby archiwum gz i ponownie go spakował --rsyncable. Ale teraz jest to dla mnie tylko pytanie akademickie.
— gogoud

Odpowiedzi:


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}

1
W ten sposób gunzip | gziptracisz nieskompresowaną nazwę i czas zapisane w pliku gz (i widziane z gzip -vNl)
— Stéphane Chazelas

@ Stéphane Chazelas: Masz rację: jeśli te informacje są istotne (nigdy nie były dla mnie istotne), tracimy je. Być może najlepszym rozwiązaniem byłoby, aby gunzip bezpośrednio wspierał tę ponowną kompresję. Może przekazać wszystkie metadane wewnętrznie.
— Raúl Salinas-Monteagudo

@ StéphaneChazelas Czy znasz kogoś, kto robi to bez strat?
— Tom Hale
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.