GNU/Linux >> LINUX-Kenntnisse >  >> Linux

rsync-Verzeichnis, damit alle Änderungen atomar erscheinen

Sie können den --link-dest= verwenden Möglichkeit. Grundsätzlich würden Sie einen neuen Ordner erstellen, alle Dateien sind fest mit dem neuen verknüpft. Wenn alles fertig ist, können Sie einfach die Ordnernamen austauschen und den alten entfernen.

Es ist unmöglich, dies unter Linux zu 100 % atomar zu machen, da es dafür keine Kernel-/VFS-Unterstützung gibt. Das Austauschen der Namen ist jedoch tatsächlich nur 2 Systemaufrufe entfernt, sodass es weniger als 1 Sekunde dauern sollte, um es abzuschließen. Dies ist nur unter Darwin (MAC/OSX) mit dem Systemaufruf exchangedata auf HFS-Dateisystemen möglich.


Ich mache etwas Ähnliches mit rsync Backups [auf Festplatte] und ich bin auf das gleiche Problem gestoßen, weil ein Daemon Dateien aktualisiert, während das Backup läuft.

Anders als viele Programme hat rsync viele verschiedene Fehlercodes [Siehe Manpage unten]. Interessant sind zwei:

23 -- teilweise Übertragung aufgrund eines Fehlers
24 -- teilweise Übertragung aufgrund verschwundener Quelldateien

Wenn rsync eine Übertragung durchführt und auf eine dieser Situationen stößt, stoppt es nicht einfach sofort. Es überspringt und fährt mit den Dateien fort, die es kann Transfer. Am Ende präsentiert es den Rückkehrcode.

Wenn Sie also den Fehler 23/24 erhalten, führen Sie einfach rsync erneut aus. Die nachfolgenden Läufe gehen viel schneller und übertragen normalerweise nur die fehlenden Dateien aus dem vorherigen Lauf. Irgendwann werden Sie einen sauberen Lauf bekommen [oder sollten].

Um atomar zu sein, verwende ich während der Übertragung ein "tmp"-Verzeichnis. Dann, wenn rsync run sauber ist, benenne ich es [atomar] in <date> um

Ich verwende auch den --link-dest Option, aber ich verwende das, um Delta-Backups zu behalten (z. B. --link-dest=yesterday für täglich)

Obwohl ich es selbst nicht verwendet habe, ist die --partial-dir=DIR kann verhindern, dass die versteckten Dateien das Backup-Verzeichnis überladen. Stellen Sie sicher, dass sich DIR auf demselben Dateisystem wie Ihr Backup-Verzeichnis befindet, damit Umbenennungen atomar sind

Während ich dies in Perl mache, habe ich ein Skript geschrieben, das das, was ich gesagt habe, mit etwas mehr Details/Präzision für Ihre spezielle Situation zusammenfasst. Es ist in tcsh-ähnlicher Syntax, [ungetestet und ein bisschen grob], aber behandeln Sie es als Pseudocode, um Ihren eigenen bash zu schreiben , perl , python Skript, wie Sie wählen. Beachten Sie, dass es keine Begrenzung für Wiederholungsversuche gibt, aber Sie können dies ganz einfach nach Ihren Wünschen hinzufügen.

#!/bin/tcsh -f
# repo_backup -- backup repos even if they change
#
# use_tmp -- use temporary destination directory
# use_partial -- use partial directory
# use_delta -- make delta backup

# set remote server name ...
set remote_server="..."

# directory on server for backups
set backup_top="/path_to_backup_top"
set backup_backups="$backup_top/backups"

# set your rsync options ...
set rsync_opts=(...)

# keep partial files from cluttering backup
set server_partial=${remote_server}:$backup_top/partial
if ($use_partial) then
    set rsync_opts=($rsync_opts --partial-dir=$server_partial)
endif

# do delta backups
if ($use_delta) then
    set latest=(`ssh ${remote_server} ls $backup_backups | tail -1`)

    # get latest
    set delta_dir="$backup_backups/$latest"

    if ($#latest > 0) then
        set rsync_opts=($rsync_opts --link-dest=${remote_server}:$delta_dir)
    endif
endif

while (1)
    # get list of everything to backup
    # set this to whatever you need
    cd /local_top_directory
    set transfer_list=(.)

    # use whatever format you'd like
    set date=`date +%Y%m%d_%H%M%S`

    set server_tmp=${remote_server}:$backup_top/tmp
    set server_final=${remote_server}:$backup_backups/$date

    if ($use_tmp) then
        set server_transfer=$server_tmp
    else
        set server_transfer=$server_final
    endif

    # do the transfer
    rsync $rsync_opts $transfer_list $server_transfer
    set code=$status

    # run was clean
    if ($code == 0) then
        # atomically install backup
        if ($use_tmp) then
            ssh ${remote_server} mv $backup_top/tmp $backup_backups/$date
        endif
        break
    endif

    # partial -- some error
    if ($code == 23) then
        continue
    endif

    # partial -- some files disappeared
    if ($code == 24) then
        continue
    endif

    echo "fatal error ..."
    exit(1)
end

Linux
  1. Rsync-Filter:Nur ein Muster kopieren?

  2. Linux – So legen Sie Standard-Dateiberechtigungen für alle Ordner/Dateien in einem Verzeichnis fest

  3. Alle Verzeichnisse in einem Verzeichnis klein schreiben?

  4. CentOS / RHEL :So legen Sie das Chroot-Gefängnis für vsftp für alle Benutzer fest

  5. Schrägstriche und der Befehl rsync

So führen Sie alle Skripte in einem Verzeichnis unter Linux aus

So verwenden Sie Rsync

Rsync ändert die Verzeichnisberechtigungen?

Linux rsync-Befehlsbeispiele

So richten Sie einen Rsync-Daemon auf Ihrem Linux-Server ein

Bash ändert das Verzeichnis nicht mehr