<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.uugrn.org/index.php?action=history&amp;feed=atom&amp;title=Snapshots_per_rsync</id>
	<title>Snapshots per rsync - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.uugrn.org/index.php?action=history&amp;feed=atom&amp;title=Snapshots_per_rsync"/>
	<link rel="alternate" type="text/html" href="https://wiki.uugrn.org/index.php?title=Snapshots_per_rsync&amp;action=history"/>
	<updated>2026-05-12T03:55:38Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in UUGRN</subtitle>
	<generator>MediaWiki 1.42.5</generator>
	<entry>
		<id>https://wiki.uugrn.org/index.php?title=Snapshots_per_rsync&amp;diff=5438&amp;oldid=prev</id>
		<title>Rabe: Katfix</title>
		<link rel="alternate" type="text/html" href="https://wiki.uugrn.org/index.php?title=Snapshots_per_rsync&amp;diff=5438&amp;oldid=prev"/>
		<updated>2007-07-15T13:22:55Z</updated>

		<summary type="html">&lt;p&gt;Katfix&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 15. Juli 2007, 13:22 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l139&quot;&gt;Zeile 139:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 139:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Kategorie:Script]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Kategorie:Script]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Kategorie:Backup]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Kategorie:Backup]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Kategorie:Anwendungsbeispiel]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Rabe</name></author>
	</entry>
	<entry>
		<id>https://wiki.uugrn.org/index.php?title=Snapshots_per_rsync&amp;diff=5228&amp;oldid=prev</id>
		<title>Rabe: Script und Funktionsweise.</title>
		<link rel="alternate" type="text/html" href="https://wiki.uugrn.org/index.php?title=Snapshots_per_rsync&amp;diff=5228&amp;oldid=prev"/>
		<updated>2007-05-29T09:57:49Z</updated>

		<summary type="html">&lt;p&gt;Script und Funktionsweise.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Dieses Script wird verwendet, um regelmäßige Snapshots kompletter Subdirectories zu archivieren.&lt;br /&gt;
Dabei verwendet es im Kern die beiden Tools [[rsync]] und [[gcp|GNU copy]] (unter Linux bekannt als [[cp]]). &lt;br /&gt;
&lt;br /&gt;
== Funktionsweise ==&lt;br /&gt;
Beim ersten Aufruf wird eine Urkopie (&amp;#039;&amp;#039;snap_0&amp;#039;&amp;#039;)erstellt (Zeile 67-71), diese wird per rsync vom Quellverzeichnis aus geschrieben (Zeile 77). War der [[rsync]] erfolgreich, wird das Verzeichnis &amp;#039;&amp;#039;work_*&amp;#039;&amp;#039; in &amp;#039;&amp;#039;snap_*&amp;#039;&amp;#039; umbenannt (Zeile 77-85). &lt;br /&gt;
&lt;br /&gt;
Bei allen weiteren Aufrufen werden dann lediglich Deltas erzeugt, indem vom jüngsten &amp;#039;&amp;#039;snap_*&amp;#039;&amp;#039;-Verzeichnis per &amp;#039;&amp;#039;GNU copy&amp;#039;&amp;#039; zunächst eine Hardlink-Kopie erzeugt wird . Dabei wird lediglich die Verzeichnisstruktur real kopiert, alle &amp;#039;&amp;#039;normalen&amp;#039;&amp;#039; Dateien werden als Hardlink erstellt und nehmen daher keinen weiteren Platz in Anspruch. &amp;#039;&amp;#039;work_1&amp;#039;&amp;#039; enthält nun eine exakte Kopie von &amp;#039;&amp;#039;snap_0&amp;#039;&amp;#039; (Zeile 63-66)&lt;br /&gt;
&lt;br /&gt;
Es folgt ein Abgleich per [[rsync]] mit dem Quellverzeichnis (Zeile 77). Dabei werden alle Dateien &amp;#039;&amp;#039;gelöscht&amp;#039;&amp;#039; und neu geschrieben, die sich geändert haben. Hat eine Datei mehr als eine Referenz, so wird beim Löschen lediglich diese Referenz entfernt, d.h. in den vorhergehenden Snapshots bleibt diese Datei erhalten. Ist der [[rsync]] erfolgreich, wird &amp;#039;&amp;#039;work_1&amp;#039;&amp;#039; in &amp;#039;&amp;#039;snap_1&amp;#039;&amp;#039; umbenannt (Zeile 77-80). &lt;br /&gt;
&lt;br /&gt;
Schlägt ein rsync-Aufruf fehl, so bleibt die unvollständige oder fehlerhafte Kopie als &amp;#039;&amp;#039;work_*&amp;#039;&amp;#039; erhalten, das darauffolgende Delta arbeitet immer auf dem zuletzt erfolgreichen &amp;#039;&amp;#039;snap_*&amp;#039;&amp;#039;. Gründe für einen fehlgeschlagenen rsync sind beispielsweise Dateien, die zwischen dem Generieren der Dateiliste und dem Kopieren verschwinden (&amp;#039;&amp;#039;vanished&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Denkbar wäre, die Zeile 77 zu ersetzen:&lt;br /&gt;
    77           if /usr/local/bin/rsync -aHW --delete --delete-before &amp;quot;${DIR}/&amp;quot; &amp;quot;${WORKDIR}&amp;quot;; then&lt;br /&gt;
&lt;br /&gt;
nach &lt;br /&gt;
    77           RSYNCCMD=&amp;quot;/usr/local/bin/rsync -aHW --delete --delete-before ${DIR}/ ${WORKDIR}&amp;quot;&lt;br /&gt;
    78           if ${RSYNCCMD} || ${RSYNCCMD};  then&lt;br /&gt;
&lt;br /&gt;
Dadurch wird der rsync im Fehlerfall 2x ausgeführt. Der zweite rsync sollte damit auch deutlich schneller durchlaufen und damit die Zeit zwischen der Erstellung des Katalogs und dem tatsächlichen Kopieren der Dateien drastisch verkürzen, was die Fehlerwahrscheinlichkeit idR senkt.&lt;br /&gt;
&lt;br /&gt;
Schlägt rsync immer fehl, kann dieses jedoch toleriert werden, so kann die Zeile 77 einfach durch &amp;#039;&amp;#039;|| true&amp;#039;&amp;#039; ergänzt werden, damit der if-Block ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel wurden die Verzeichnisse &amp;#039;&amp;#039;snap_1&amp;#039;&amp;#039; genannt, im realen betrieb werden hier timestamps verwendet, siehe Zeile 28-32.&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
Anders als bei einer ausgewachsenen Versionsverwaltung müssen die Daten nicht explizit in einem Repository angemeldet werden, die Dateien &amp;quot;wissen&amp;quot; nichts von snapshots. Dieses Verfahren eignet sich beispielsweise dafür, statische Binärdaten wie etwa Multimedia-Dateien etc. zu versionieren. &lt;br /&gt;
&lt;br /&gt;
Bearbeitet man beispielsweise ein Bild und speichert es unter gleichem Namen wieder ab, geht die alte Version im Quellverzeichnis erstmal verloren. Im snapshot-Verzeichnis jedoch bleibt die alte Version erhalten.&lt;br /&gt;
&lt;br /&gt;
Verzeichnisse, die überwiegend wachsende Dateien enthalten, wie etwa Logfiles, sind nur begrenzt sinnvoll für die snapshots, da diese Dateien bei JEDEM Durchlauf komplett neu kopiert werden. Dabei entstehen zwar funktionierende Snapshots, jedoch werden auch geringe Änderungen mit dem vollen Speicherplatz archiviert, keine Deltas.&lt;br /&gt;
&lt;br /&gt;
== Script ==&lt;br /&gt;
     1  #! /bin/sh&lt;br /&gt;
     2  #&lt;br /&gt;
     3  # Verzeichnis-Snapshots erstellen mit gnu-copy(hardlinks) und rsync&lt;br /&gt;
     4  #&lt;br /&gt;
     5  #&lt;br /&gt;
     6  #&lt;br /&gt;
     7  # Aufruf:&lt;br /&gt;
     8  # $0 /path/to/dir/&lt;br /&gt;
     9  #&lt;br /&gt;
    10  # --&amp;gt; /data/snapshot/path_to_dir/&amp;lt;timestamp&amp;gt;/...&lt;br /&gt;
    11&lt;br /&gt;
    12&lt;br /&gt;
    13  SNAPSHOTHOME=/data/snapshot&lt;br /&gt;
    14&lt;br /&gt;
    15  # Symlinks etc auflösen, benötigen den absoluten pfad&lt;br /&gt;
    16  abspath()&lt;br /&gt;
    17  {&lt;br /&gt;
    18    (cd $1 &amp;amp;&amp;amp; pwd -P) 2&amp;gt;/dev/null&lt;br /&gt;
    19  }&lt;br /&gt;
    20&lt;br /&gt;
    21  # Zielverzeichnis ermitteln&lt;br /&gt;
    22  snapdir()&lt;br /&gt;
    23  {&lt;br /&gt;
    24    echo -n &amp;quot;${SNAPSHOTHOME}/&amp;quot;&lt;br /&gt;
    25    echo &amp;quot;$1&amp;quot;| tr &amp;#039;/ &amp;#039; &amp;#039;__&amp;#039;&lt;br /&gt;
    26  }&lt;br /&gt;
    27&lt;br /&gt;
    28  # Zeitstempel ermitteln&lt;br /&gt;
    29  timestamp()&lt;br /&gt;
    30  {&lt;br /&gt;
    31    date +%Y%m%d%H%M%S&lt;br /&gt;
    32  }&lt;br /&gt;
    33&lt;br /&gt;
    34  # jüngsten (vollständigen) snapshot in $SNAPDIR ermitteln&lt;br /&gt;
    35  getlatest()&lt;br /&gt;
    36  {&lt;br /&gt;
    37    ls -1dr &amp;quot;$SNAPDIR&amp;quot;/snap_20*/  | head -n 1 2&amp;gt;/dev/null&lt;br /&gt;
    38  }&lt;br /&gt;
    39&lt;br /&gt;
    40  if [ $# -ge 1 ]; then&lt;br /&gt;
    41    while [ -n &amp;quot;$1&amp;quot; ]; do&lt;br /&gt;
    42      DIR=&amp;quot;$(abspath &amp;quot;$1&amp;quot;)&amp;quot;&lt;br /&gt;
    43      if [ -d &amp;quot;${DIR}&amp;quot; ]; then&lt;br /&gt;
    44        SNAPDIR=$(snapdir &amp;quot;${DIR}&amp;quot;)&lt;br /&gt;
    45        echo &amp;quot;$0: Bearbeite ${DIR} ... &amp;quot;&lt;br /&gt;
    46&lt;br /&gt;
    47        # Anlegen, falls nicht vorhanden&lt;br /&gt;
    48        if [ ! -d &amp;quot;${SNAPDIR}&amp;quot; ]; then&lt;br /&gt;
    49          mkdir -p &amp;quot;${SNAPDIR}&amp;quot; 2&amp;gt;/dev/null&lt;br /&gt;
    50        fi&lt;br /&gt;
    51&lt;br /&gt;
    52        # Weitermachen, falls jetzt vorhanden&lt;br /&gt;
    53        if [ -d &amp;quot;${SNAPDIR}&amp;quot; ]; then&lt;br /&gt;
    54          echo &amp;quot;$0: Snapshot von $DIR nach $SNAPDIR&amp;quot;&lt;br /&gt;
    55          TS=$(timestamp)&lt;br /&gt;
    56          LATESTSNAP=&amp;quot;$(getlatest)&amp;quot;&lt;br /&gt;
    57          WORKDIR=&amp;quot;${SNAPDIR}/work_${TS}&amp;quot;&lt;br /&gt;
    58          FINISHDIR=&amp;quot;${SNAPDIR}/snap_${TS}&amp;quot;&lt;br /&gt;
    59&lt;br /&gt;
    60          # jüngsten snapshot ermitteln&lt;br /&gt;
    61          # falls vorhanden mit GNU-copy als hardlink-Kopie anlegen&lt;br /&gt;
    62          # oder leeres Verzeichnis erstellen&lt;br /&gt;
    63          if [ -n &amp;quot;${LATESTSNAP}&amp;quot; ]; then&lt;br /&gt;
    64            # Alter snapshot besteht, gcp-hardlink erzeugen&lt;br /&gt;
    65            echo &amp;quot;$0: Hardlink-Kopie ${LATESTSNAP} --&amp;gt; ${WORKDIR} erzeugen (gcp)&amp;quot;&lt;br /&gt;
    66            /usr/local/bin/gcp -al &amp;quot;${LATESTSNAP}&amp;quot; &amp;quot;${WORKDIR}&amp;quot;&lt;br /&gt;
    67          else&lt;br /&gt;
    68            # Kein Alter snapshot vorhanden, neu (leer) anlegen&lt;br /&gt;
    69            echo &amp;quot;$0: Leeres ${WORKDIR} anlegen ...&amp;quot;&lt;br /&gt;
    70            mkdir &amp;quot;${WORKDIR}&amp;quot;&lt;br /&gt;
    71          fi&lt;br /&gt;
    72&lt;br /&gt;
    73          # Quellverzeichnis ins Arbeitsverzeichnis rsync&amp;#039;en&lt;br /&gt;
    74          # DIR -&amp;gt; WORKDIR&lt;br /&gt;
    75          if [ -d &amp;quot;${WORKDIR}&amp;quot; ]; then&lt;br /&gt;
    76           echo &amp;quot;$0: rsync ${DIR}/ -&amp;gt; ${WORKDIR} ...&amp;quot;&lt;br /&gt;
    77           if /usr/local/bin/rsync -aHW --delete --delete-before &amp;quot;${DIR}/&amp;quot; &amp;quot;${WORKDIR}&amp;quot;; then&lt;br /&gt;
    78             if mv &amp;quot;${WORKDIR}&amp;quot; &amp;quot;${FINISHDIR}&amp;quot; ; then&lt;br /&gt;
    79               echo &amp;quot;$0: ${DIR} --&amp;gt; ${FINISHDIR} abgeschlossen. OK.&amp;quot;&lt;br /&gt;
    80             else&lt;br /&gt;
    81               echo &amp;quot;$0: Fehler beim Abschließen: &amp;quot;${WORKDIR}&amp;quot; --&amp;gt; ${FINISHDIR}&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    82             fi&lt;br /&gt;
    83           else&lt;br /&gt;
    84             echo &amp;quot;$0; Fehler bei rsync ${DIR}/ --&amp;gt; ${WORKDIR}&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    85           fi&lt;br /&gt;
    86          else&lt;br /&gt;
    87            echo &amp;quot;$0: ${WORKDIR} nicht gefunden, konnte nicht erstellt werden&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    88          fi&lt;br /&gt;
    89        else&lt;br /&gt;
    90          echo &amp;quot;$0: $SNAPDIR nicht gefunden, konnte nicht angelegt werden oder kein Verzeichnis&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    91        fi&lt;br /&gt;
    92      else&lt;br /&gt;
    93        echo &amp;quot;$0: $1 nicht gefunden&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    94      fi&lt;br /&gt;
    95      shift&lt;br /&gt;
    96    done&lt;br /&gt;
    97  else&lt;br /&gt;
    98    echo &amp;quot;$0: Fehlende Parameter&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    99    echo &amp;quot;Aufruf:&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
   100    echo &amp;quot;$0 /path/to/dir [/path2/to/dir] ...&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
   101    exit 1&lt;br /&gt;
   102  fi&lt;br /&gt;
   103&lt;br /&gt;
   104&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Script]]&lt;br /&gt;
[[Kategorie:Backup]]&lt;/div&gt;</summary>
		<author><name>Rabe</name></author>
	</entry>
</feed>