Dieser Text befindet sich gegenwärtig in Bearbeitung, unterliegt ständigen Änderungen und kann dadurch nicht stets akkurat irgendeine freigegebene Version der Software Apache™ Subversion® beschreiben. Das Speichern dieser Seite als Lesezeichen oder andere auf diese Seite zu verweisen, ist keine so gute Idee. Besuchen Sie http://www.svnbook.com/, um stabile Versionen dieses Buchs zu erhalten.

Projektarchiv-Wartung

Die Wartung eines Subversion-Projektarchivs kann abschreckend sein, was an der Komplexität liegt, die Systemen innewohnt, die auf Datenbanken aufbauen. Die Arbeit gut zu machen, bedeutet, die Werkzeuge zu kennen – was sie sind, wann sie zu verwenden sind und wie. Dieser Abschnitt stellt Ihnen die Projektarchiv-Verwaltungswerkzeuge vor, die Subversion mitbringt und erörtert, wie sie gehandhabt werden, um Aufgaben zu erledigen, wie etwa Projektarchiv-Datenmigration, Aktualisierungen, Sicherungen und Aufräumarbeiten.

Der Werkzeugkasten eines Administrators

Subversion stellt eine Handvoll Dienstprogramme zur Verfügung, die nützlich zum Erstellen, Untersuchen, Verändern und Reparieren Ihres Projektarchivs sind. Wir wollen uns diese Werkzeuge einmal genauer ansehen.

svnadmin

Das Programm svnadmin ist der beste Freund des Projektarchiv-Administrators. Neben der Fähigkeit, Subversion-Projektarchive zu erzeugen, erlaubt Ihnen dieses Programm verschiedene Wartungsarbeiten auf diesen Projektarchive auszuführen. Die Syntax von svnadmin ist ähnlich wie bei anderen Kommandozeilen=Programmen von Subversion:

$ svnadmin help
Aufruf: svnadmin UNTERBEFEHL ARCHIV_PFAD [Optionen & Parameter ...]
Geben Sie »svnadmin help <Unterbefehl>« ein, um Hilfe zu einem Unterbefehl
          zu erhalten.
Geben Sie »svnadmin --version« ein, um die Programmversion und die Datei-
          systemmodule zu sehen.

Verfügbare Unterbefehle:
   crashtest
   create
   deltify
…

Früher in diesem Kapitel (in „Anlegen des Projektarchivs“), wurde uns der Unterbefehl svnadmin create vorgestellt. Die meisten anderen Unterbefehle von svnadmin werden wir später in diesem Kapitel behandeln. Und in svnadmin Referenz – Subversion Projektarchiv-Verwaltung können Sie in einer vollständigen Aufstellung der Unterbefehle nachlesen, was jeder zu bieten hat.

svnlook

svnlook ist ein von Subversion mitgeliefertes Dienstprogramm zum Untersuchen der mannigfaltigen Revisionen und Transaktionen (bei denen es sich um Revisionen in Entstehung handelt) in einem Projektarchiv. Kein Teil dieses Programms versucht, das Projektarchiv zu verändern. svnlook wird üblicherweise von Projektarchiv-Hooks verwendet, um die abzuliefernden Änderungen zu melden (im Fall des pre-commit-Hooks) oder die gerade an das Projektarchiv übertragen wurden (im Fall des post-commit-hooks). Ein Projektarchiv-Administrator kann dieses Programm zur Diagnose benutzen.

svnlook besitzt eine überschaubare Syntax:

$ svnlook help
Aufruf: svnlook UNTERBEFEHL ARCHIV_PFAD [Optionen & Parameter ...]
Hinweis: Alle Unterbefehle, die die Parameter »--revision« und »--transaction«
         akzeptieren, werden ohne diese Parameter die neueste
         Revision des Projektarchivs verwenden.
Geben Sie »svnlook help <Unterbefehl>« ein, um Hilfe zu einem Unterbefehl
         zu erhalten.
Geben Sie »svnlook --version« ein, um die Programmversion und die Datei-
         systemmodule zu sehen.
…

Die meisten Unterbefehle von svnlook können entweder auf einem Revisions- oder auf einem Transaktionsbaum arbeiten, indem sie Informationen über den Baum an sich ausgeben oder darüber, inwiefern er sich von einer früheren Revision des Projektarchivs unterscheidet. Sie verwenden die Optionen --revision (-r) und --transaction (-t), um die zu untersuchende Revision bzw. Transaktion anzugeben. Ohne eine der Optionen --revision (-r) und --transaction (-t) untersucht Subversion die jüngste (oder HEAD) Revision des Projektarchivs. Das heißt, die beiden folgenden Befehle machen genau dasselbe, wenn 19 die jüngste Revision im Projektarchiv unter /var/svn/repos ist:

$ svnlook info /var/svn/repos
$ svnlook info /var/svn/repos -r 19

Eine Ausnahme von diesen Regeln zu Unterbefehlen ist der Unterbefehl svnlook youngest, der keine Optionen entgegennimmt und einfach die jüngste Revisionsnummer des Projektarchivs ausgibt:

$ svnlook youngest /var/svn/repos
19
$
[Anmerkung] Anmerkung

Beachten Sie, dass Sie nur Transaktionen untersuchen können, die noch nicht übertragen sind. Die meisten Projektarchive haben keine derartigen Transaktionen, da Transaktionen entweder übertragen (in diesem Fall sollten Sie darauf mit der Option --revision (-r) zugreifen) oder abgebrochen und entfernt sind.

Die Ausgabe svnlook ist so gestaltet, dass sie sowohl für Menschen als auch für Maschinen lesbar ist. Nehmen wir zum Beispiel die Ausgabe des Unterbefehls svnlook info:

$ svnlook info /var/svn/repos
sally
2002-11-04 09:29:13 -0600 (Mo, 04. Nov 2002)
43
Den üblichen griechischen
Baum hinzugefügt.
$

Die Ausgabe von svnlook info besteht aus dem Folgenden in entsprechender Reihenfolge:

  1. Der Autor gefolgt von einem Zeilenvorschub

  2. Das Datum gefolgt von einem Zeilenvorschub

  3. Die Anzahl der Zeichen der Protokollnachricht gefolgt von einem Zeilenvorschub.

  4. Die eigentliche Protokollnachricht gefolgt von einem Zeilenvorschub

Diese Ausgabe ist für Menschen lesbar, d.h., Dinge wie der Zeitstempel werden als Text dargestellt statt als irgendetwas Obskures (wie die Anzahl der Nanosekunden seit der Mann von Bofrost das letzte Mal da war). Jedoch ist die Ausgabe auch maschinenlesbar – weil die Protokollnachricht mehrere Zeilen umfassen und von der Länge her unbegrenzt sein kann, liefert svnlook die Länge der Nachricht vor der eigentlichen Nachricht. Das erlaubt Skripten und anderen Programmen, die um diesen Befehl herum geschrieben wurden, intelligente Entscheidungen in Bezug auf die Protokollnachricht zu treffen, etwa wie viel Speicher für die Nachricht anzufordern ist oder zumindest wie viele Bytes zu überspringen sind, falls diese Ausgabe nicht das letzte Stück im Datenstrom sein sollte.

svnlook kann eine Auswahl anderer Abfragen ausführen: Teilmengen der bereits erwähnten Informationen ausgeben, versionierte Verzeichnisbäume rekursiv auflisten, berichten, welche Pfade in einer bestimmten Revision oder Transaktion verändert wurden, textuelle und property-basierte Unterschiede an Dateien und Verzeichnissen aufzeigen, usw. Siehe svnlook Referenz – Subversion Projektarchiv-Untersuchung für eine vollständige Referenz der Funktionen von svnlook.

svndumpfilter

Obwohl es nicht das am meisten verwendete Werkzeug im Sortiment des Administrators sein wird, bietet svndumpfilter eine ganz besondere Art von nützlichen Funktionen – die Fähigkeit, schnell und einfach Datenströme aus der Projektarchiv-Historie zu verändern, indem es als ein pfadbasierter Filter arbeitet.

Die Syntax von svndumpfilter lautet wie folgt:

$ svndumpfilter help
Aufruf: svndumpfilter UNTERBEFEHL [Optionen & Parameter ...]
Geben Sie »svndumpfilter help <Unterbefehl>« ein, um Hilfe zu einem
          Unterbefehl zu erhalten.
Geben Sie »svndumpfilter --version« ein, um die Programmversion zu sehen.

Verfügbare Unterbefehle:
   exclude
   include
   help (?, h)

Es gibt nur zwei interessante Unterbefehle: svndumpfilter exclude und svndumpfilter include. Sie erlauben Ihnen, zwischen einer impliziten oder expliziten Einbeziehung von Pfaden im Datenstrom zu wählen. Sie können mehr über diese Unterbefehle und den einzigartigen Zweck von svndumpfilter später in diesem Kapitel unter „Filtern der Projektarchiv-Historie“ erfahren.

svnrdump

Das Programm svnrdump ist einfach im Wesentlichen eine Kombination netzfähiger Ausprägungen der Unterbefehle svnadmin dump und svnadmin load.

$ svnrdump help 
Aufruf: svnrdump UNTERBEFEHL URL [-r VON[:BIS]]
Geben Sie »svnrdump help <Unterbefehl>« ein, um Hilfe zu einem
Unterbefehl zu erhalten.
Geben Sie »svnrdump --version« ein, um die Programmversion und die
Zugriffsmodule zu sehen.

Verfügbare Unterbefehle:
   dump
   load
   help (?, h)

$

Wir wedden sie Verwendung von svnrdump und dem vorher erwähnten Befehl svnadmin später in diesem Kapitel erörtern (siehe „Projektarchiv-Daten woanders hin verschieben“).

svnsync

Der Befehl svnsync, der in Subversion 1.4 neu hinzugekommen ist, bietet Funktionen zum Verwalten eines Nur-Lese-Spiegels des Subversion-Projektarchivs. Das Programm hat eine Aufgabe – die versionierte Historie eines Projektarchivs in ein anderes zu übertragen. Und während es nicht viele Möglichkeiten gibt, dies zu tun, liegt seine hauptsächliche Stärke darin, das es aus der Ferne eingesetzt werden kann – das Quell- und Ziel-Projektarchiv können auf verschiedenen Rechnern liegen und auf einem anderen Rechner als svnsync selbst.

Wie Sie vielleicht erwarten, hat svnsync eine Syntax, die allen anderen Programmen aus diesem Kapitel gleicht:

$ svnsync help
Aufruf: svnsync UNTERBEFEHL ZIEL_URL [Optionen & Parameter ...]
Geben Sie »svnsync help <Unterbefehl>« ein, um Hilfe zu einem
          Unterbefehl zu erhalten.
Geben Sie »svnsync --version« ein, um die Programmversion und die Zugriffs-
          module zu sehen.

Verfügbare Unterbefehle:
   initialize (init)
   synchronize (sync)
   copy-revprops
   info
   help (?, h)

$

Später in diesem Kapitel werden wir mehr über das Replizieren von Projektarchiven mit svnsync reden (siehe „Projektarchiv Replikation“).

fsfs-reshard.py

Obwohl es kein offizielles Glied in der Werkzeugkette von Subversion ist, handelt es sich bei dem Skript fsfs-reshard.py (zu finden im Verzeichnis tools/server-side des Subversion-Quelltext-Paketes) um ein nützliches Werkzeug zur Leistungssteigerung für Administratoren von FSFS-basierten Subversion-Projektarchiven. FSFS-Projektarchive verwenden einzelne Dateien, die die zu einer Revision gehörenden Eigenschaften beherbergen. Manchmal liegen alle dieser Dateien in einem einzelnen Verzeichnis; manchmal werden sie über viele Verzeichnisse verteilt.

Die frühesten herausgegebenen FSFS Versionen brachten alle Revisionsdateien in einem einzelnen Verzeichnis unter, das während der gesamten Lebenszeit Ihres Projektarchivs wuchs: eine Datei pro Revision. Auf Systemen, die die Anzahl von Dateien pro Verzeichnis streng limitiert haben, erzeugte das Probleme und war sogar ein Leistungsproblem auf Systemen, die diese Begrenzung nicht hatten oder diese Grenzen hoch genug waren.

Beginnend mit Version 1.5 erstellt Subversion FSFS-basierte Projektarchive mit mit einem etwas veränderten Layout, bei dem der Inhalt des Verzeichnisses mit den Revisionsdateien (und anderer stets wachsender Verzeichnisse) in Scherben zerlegt wird, oder über mehrere Unterverzeichnisse verteilt wird. Das kann erheblich zur Verkürzung der Zeit beitragen, die das System benötigt, um irgendeine dieser Dateien zu finden, und somit die Gesamtleistung von Subversion beim Lesen des Projektarchivs erhöhen.

Die Anzahl der erlaubten Dateien in einem gegebenen Unterverzeichnis lässt sich konfigurieren (obwohl die Standardwerte für die meisten bekannten Plattformen angemessen sind); die Änderung dieser Konfiguration nachdem das Projektarchiv bereits einige Zeit in Betrieb war, könnte aber dazu führen, dass Subversion gesuchte Dateien nicht mehr findet. Hier kommt der Befehl fsfs-reshard.py ins Spiel.

fsfs-reshard.py mischt die Dateistruktur des Projektarchivs, indem es sie gemäß der Anzahl der gewünschten Unterverzeichnisse neu anordnet und die Konfiguration des Projektarchivs aktualisiert, um diese Änderung zu bewahren. In Verbindung mit dem Befehl svnadmin upgrade erweist sich das als besonders nützlich, wenn ein Projektarchiv aus der Zeit vor Subversion 1.5 (mit unverteilten Verwaltungsdateien) in das neueste Dateisystem-Format überführt werden soll und dessen Dateien aufteilt (was Subversion nicht automatisch für Sie macht). Dieses Skript kann ebenfalls dazu verwendet werden, um ein bereits aufgeteiltes Projektarchiv noch feiner einzustellen.

Berichtigung des Protokolleintrags

Manchmal kommt es vor, dass ein Anwender einen Fehler im Protokolleintrag gemacht hat (einen Tippfehler oder vielleicht eine Fehlinformation). Falls das Projektarchiv entsprechend eingestellt ist (indem der Hook pre-revprop-change verwendet wird; siehe „Erstellen von Projektarchiv-Hooks“), um Änderungen am Protokolleintrag vorzunehmen nachdem die Übergabe abgeschlossen ist, kann der Anwender den Protokolleintrag aus der Ferne mit dem Befehl svn propset (siehe svn propset (pset, ps) in svn Referenz – Subversion-Kommandozeilen-Client) berichtigen. Wegen der Möglichkeit, dadurch für immer Informationen zu verlieren, sind Subversion-Projektarchive allerdings standardmäßig nicht so eingestellt, dass Änderungen an unversionierten Eigenschaften erlaubt sind – außer für einen Administrator.

Falls ein Protokolleintrag durch einen Administrator geändert werden muss, kann das mit svnadmin setlog geschehen. Dieser Befehl ändert den Protokolleintrag (die Eigenschaft svn:log) einer gegebenen Revision eines Projektarchivs, indem der neue Inhalt aus einer angegebenen Datei gelesen wird.

$ echo "Hier ist der neue, korrekte Protokolleintrag" > newlog.txt
$ svnadmin setlog myrepos newlog.txt -r 388

Auch der Befehl svnadmin setlog ist standardmäßig durch dieselben Schutzmechanismen gegen die Veränderung unversionierter Eigenschaften eingeschränkt wie ein Client aus der Ferne – die Hooks pre-revprop-change und post-revprop-change werden immer noch ausgelöst und müssen entsprechend eingestellt werden, um solche Änderungen zuzulassen. Allerdings kann ein Administrator diese Schutzmechanismen umgehen, indem er die Option --bypass-hooks an den Befehl svnadmin setlog übergibt.

[Warnung] Warnung

Denken Sie trotzdem daran, dass beim Umgehen der Hooks auch Dinge umgangen werden wie E-Mail-Benachrichtigungen bei Eigenschafts-Änderungen, Sicherungssysteme, die Änderungen an unversionierten Eigenschaften verfolgen, usw. Mit anderen Worten: Seien Sie sehr vorsichtig bei der Auswahl dessen, was Sie ändern und wie Sie es ändern.

Plattenplatzverwaltung

Obwohl die Kosten für Speicherplatz in den letzten Jahren unglaublich gefallen sind, ist Plattenplatz immer noch ein berechtigtes Anliegen für Administratoren, die große Mengen von Daten zu versionieren haben. Jedes im aktiven Projektarchiv gespeicherte Bisschen Information über die Versionshistorie muss zu einem anderen Ort gesichert werden; vielleicht sogar öfter, falls eine zyklische Sicherungsstrategie angewendet wird. Es ist zweckdienlich zu wissen, welche Teile von Subversions Projektarchiv am Ort verbleiben müssen, welche gesichert werden müssen und welche ruhig entfernt werden können.

Wie Subversion Plattenplatz spart

Um das Projektarchiv klein zu halten, verwendet Subversion innerhalb des Projektarchivs Delta-Kodierung (oder Deltaspeicherung). Unter Delta-Kodierung wird die Kodierung eines Datensatzes als eine Sammlung von Unterschieden gegenüber einem anderen Datensatz verstanden. Falls die beiden Datensätze sehr ähnlich sind, bewirkt diese Delta-Kodierung eine Einsparung an Speicherplatz für den als Delta gespeicherten Datensatz – anstatt den Platz der Originaldaten zu belegen, wird hierbei nur soviel Platz benötigt, um zu sagen: Schau mal, ich sehe genau so aus, wie der andere Datensatz da drüben, bis auf die folgenden paar Änderungen. Das Ergebnis ist, dass die meisten der Daten im Projektarchiv, die normalerweise recht voluminös sind – nämlich der Inhalt versionierter Dateien – in einer viel geringeren Größe gespeichert werden als der ursprüngliche Volltext dieser Daten.

Während die delta-kodierte Speicherung bereits von Anfang an ein Teil des Designs von Subversion gewesen ist, sind im Laufe der Jahre zusätzliche Verbesserungen vorgenommen worden. Subversion Projektarchive, die mit Subversion 1.4 oder neuer erstellt worden sind, ziehen Nutzen aus der Komprimierung der Volltext-Repräsentation von Dateiinhalten. Projektarchiv, die mit Subversion 1.6 oder neuer erstellt worden sind, genießen darüber hinaus den durch geteilte Repräsentation gesparten Plattenplatz, eine Funktionalität, die es mehreren Dateien oder Dateirevisionen mit identischen Dateiinhalt erlaubt, auf eine einzelne geteilte Instanz dieser Daten zu verweisen, anstatt eine eigene, getrennte Kopie davon vorhalten zu müssen.

Entfernen unvollendeter Transaktionen

Obwohl es selten vorkommt, gibt es Umstände, unter denen der Übergabeprozess mit einem Fehler abbricht und die Reste einer Revision in Spe hinterlässt – eine unvollendete Transaktion samt aller Datei- und Verzeichnisänderungen, die dazugehören. Dies kann aus verschiedenen Gründen passieren: Vielleicht wurde die Operation des Clients vom Anwender unsauber beendet oder es trat mittendrin ein Netzfehler auf. Aus welchem Grund auch immer, es können unvollendete Transaktionen auftreten. Sie verursachen keine tatsächlichen Schäden, außer Plattenplatz zu verschwenden. Ein penibler Administrator möchte sie vielleicht dennoch entfernen.

Sie können den Befehl svnadmin lstxns verwenden, um die Namen der aktuell ausstehenden Transaktionen anzuzeigen:

$ svnadmin lstxns myrepos
19
3a1
a45
$

Jeder Eintrag der Ausgabe kann dann mit dem Befehl svnlook (und seiner Option --transaction (-t)) aufgerufen werden, um festzustellen, wer die Transaktion erzeugt hat, wann sie erzeugt wurde und welche Änderungen sie beinhaltet – Informationen, die bei der Entscheidung helfen können, ob eine Transaktion ein sicherer Kandidat zum Löschen ist! Wenn Sie tatsächlich eine Transaktion löschen wollen, kann deren Name an den Befehl svnadmin rmtxns übergeben werden, der dann die Transaktion aufräumt. svnadmin rmtxns kann seine Eingabe auch direkt aus der Ausgabe von svnadmin lstxns beziehen!

$ svnadmin rmtxns myrepos `svnadmin lstxns myrepos`
$

Falls Sie auf diese Weise diese beiden Unterbefehle verwenden, sollten Sie vorübergehend das Projektarchiv für Clients unzugänglich machen. So kann niemand eine berechtigte Transaktion beginnen, bevor Sie aufgeräumt haben. Beispiel 5.3, „txn-info.sh (ausstehende Transaktionen anzeigen)“ enthält ein kleines Shell-Skript, das schnell eine Übersicht über jede ausstehende Transaktion in Ihrem Projektarchiv erzeugen kann.

Beispiel 5.3. txn-info.sh (ausstehende Transaktionen anzeigen)

#!/bin/sh

### Erzeuge Informationen über alle ausstehenden Transaktionen eines
### Subversion Projektarchivs.

REPOS="${1}"
if [ "x$REPOS" = x ] ; then
  echo "Aufruf: $0 REPOS_PATH"
  exit
fi

for TXN in `svnadmin lstxns ${REPOS}`; do 
  echo "---[ Transaktion ${TXN} ]-------------------------------------------"
  svnlook info "${REPOS}" -t "${TXN}"
done

Die Ausgabe des Skriptes ist im Grunde genommen eine Aneinanderreihung mehrerer Teile von svnlook info-Ausgaben (siehe „svnlook“) und sieht etwa so aus:

$ txn-info.sh myrepos
---[ Transaktion 19 ]-------------------------------------------
sally
2001-09-04 11:57:19 -0500 (Di, 04. Sep 2001)
0
---[ Transaktion 3a1 ]-------------------------------------------
harry
2001-09-10 16:50:30 -0500 (Mo, 10. Sep 2001)
39
Versuch, über eine schlechte Netzverbindung abzuliefern.
---[ Transaktion a45 ]-------------------------------------------
sally
2001-09-12 11:09:28 -0500 (Mi, 12. Sep 2001)
0
$

Eine vor langer Zeit aufgegebene Transaktion bedeutet normalerweise eine Art fehlgeschlagenen oder unterbrochenen Übergabeversuch. Der Zeitstempel einer Transaktion kann eine interessante Information sein – ist es beispielsweise wahrscheinlich, dass eine vor neun Monaten begonnene Operation immer noch aktiv ist?

Kurz gesagt, Entscheidungen zur Bereinigung von Transaktionen sollten klug getroffen werden. Verschiedene Informationsquellen – hierzu gehören die Fehler- und Zugriffs-Protokolldateien von Apache, die operativen Protokolldateien von Subversion, die Revisions-Historie von Subversion usw. – können während des Entscheidungsprozesses hinzugezogen werden. Natürlich kann sich ein Administrator auch einfach mit dem Eigentümer einer anscheinend abgebrochenen Transaktion in Verbindung setzen (z.B., per E-Mail), um sicherzustellen, dass die Transaktion sich tatsächlich in einem Zombie-Zustand befindet.

FSFS Filtersystem packen

FSFS-Projektarchive beinhalten Dateien, die die in einer einzelnen Revision gemachten Änderungen beschreiben und Dateien, die die Revisions-Eigenschaften beinhalten, die mit einer einzelnen Revision verknüpft sind. Projektarchive, die mit früheren Versionen von Subversion als 1.5 erzeugt wurden, speichern diese Dateien in zwei Verzeichnissen – jeweils eins für jeden Dateitypen Während neue Revisionen an das Projektarchiv übertragen werden, hinterlegt Subversion mehr Dateien in den beiden Verzeichnissen; im Lauf der Zeit kann die Anzahl dieser Dateien ziemlich groß werden. Es wurde bei bestimmten netzbasierten Dateisystemen wurde beobachtet, dass dies zu Leistungseinbußen führt..

Das erste Problem besteht darin, dass das Betriebssystem innerhalb kurzer Zeit auf viele verschiedene Dateien beziehen muss. Das führt zur ineffektiven Verwendung von Zwischenspeicherungen der Platte und hat zur Folge, dass bei großen Platten viel Zeit zum Suchen verbraucht wird. Daher kommt es beim Zugriff von Subversion auf versionierte Daten zu Leistungseinbußen.

Das zweite Problem ist etwas subtiler. Aufgrund der Art und Weise wie die meisten Dateisysteme Plattenplatz zuweisen, benötigt eine Datei mehr Platz, als sie eigentlich belegt. Der Umfang des zusätzlichen Platzes, um eine einzelne Datei unterzubringen, kann, je nach verwendetem Dateisystem durchschnittlich irgendwo zwischen 2 und 16 Kilobyte pro Datei liegen. Das bedeutet pro Revision eine Einbuße bei der Plattennutzung für Projektarchive auf FSFS Basis. Besonders deutlich wird der Effekt bei Projektarchiven mit vielen kleinen Revisionen, da hier platzmäßig die Kosten der Speicherung der Revisionsdatei schnell den Umfang der eigentlich zu speichernden Daten überschreiten.

Zur Lösung dieser Probleme führte Subversion 1.6 den Befehl svnadmin pack ein. Durch das Aneinanderfügen aller Dateien einer vollständigen Scherbe in eine einzelne pack-Datei und das anschließende Entfernen der ursprünglichen Dateien, die pro Revision angelegt wurden, verringert svnadmin pack die Anzahl der Dateien innerhalb einer gegebenen Scherbe auf nur eine einzelne Datei. Das kommt den Zwischenspeichern des Dateisystems entgegen und verringert die Anzahl der Kosten für Dateispeicherung auf eins.

Subversion kann bestehende zerlegte Projektarchive packen, die auf das Dateisystemformat von 1.6 oder neuer aktualisiert worden sind (siehe svnadmin upgrade in svnadmin Referenz – Subversion Projektarchiv-Verwaltung). Lassen Sie dafür einfach svnadmin pack über das Projektarchiv laufen:

$ svnadmin pack /var/svn/repos
Packe 0...erledigt.
Packe 1...erledigt.
Packe 2...erledigt.
…
Packe 34...erledigt.
Packe 35...erledigt.
Packe 36...erledigt.
$

Da der Packprozess die benötigten Sperren erlangt, bevor er seine Arbeit beginnt, können Sie ihn auf in Benutzung befindliche Projektarchive anwenden oder sogar als Teil eines Hooks nach der Übergabe. Das erneute Packen bereits gepackter Scherben ist legal, hat allerdings keine Auswirkungen auf den Plattenplatzverbrauch des Projektarchivs.

svnadmin pack hat keine Auswirkungen auf Subversion-Projektarchive auf BDB-Basis.

Projektarchiv-Daten woanders hin verschieben

Ein Subversion-Dateisystem hält seine Daten in Dateien, die auf eine Art und Weise über das Projektarchiv verstreut sind, die im Allgemeinen nur die Subversion-Entwickler selbst verstehen (und auch nur sie interessieren). Allerdings können es bestimmte Umstände erforderlich machen, alle Daten oder nur Teile davon in ein anderes Projektarchiv zu kopieren oder zu verschieben.

Subversion stellt solche Funktionen durch Projektarchiv-Auszugs-Datenströme (repository dump streams) bereit. Ein Projektarchiv-Auszugs-Datenstrom (oft als Auszugsdatei bezeichnet, wenn er als Datei auf Platte gespeichert wird) ist ein portables, flaches Dateiformat, das die zahlreichen Revisionen in Ihrem Projektarchiv beschreibt – was geändert wurde, von wem usw. Dieser Datenstrom ist der primäre Mechanismus zum Herumschieben der versionierten Historie – als Ganzes oder in Teilen, mit oder ohne Änderung – zwischen Projektarchiven. Und Subversion stellt die Werkzeuge zum Erzeugen und Laden dieser Datenströme zur Verfügung: die Unterbefehle svnadmin dump bzw. svnadmin load und das Programm svnrdump.

[Warnung] Warnung

Obwohl das Format der Subversion Auszugsströme menschenlesbare Teile enthält und das Format eine gewohnte Struktur besitzt (es gleicht einem RFC 822 Format, das meistens für E-Mail verwendet wird), ist es kein reines Textformat. Es ist ein Binärformat, das sehr empfindlich gegenüber Herumgepfusche ist. Beispielsweise würden viele Texteditoren die Datei beschädigen, indem sie automatisch die Zeilenenden umformen.

Es gibt viele Gründe, Auszüge von Subversion-Projektarchiv-Daten zu machen und zu laden. In der Anfangsphase von Subversion war der häufigste Grund die Weiterentwicklung von Subversion an sich. Während Subversion reifte, gab es Zeiten, als Änderungen an der Datenbankbasis zu Kompatibilitätsproblemen mit früheren Projektarchiv-Versionen führten, so dass Anwender mit der vorherigen Version von Subversion Auszüge von ihren Projektarchiv-Daten machen und sie mit der neueren Version von Subversion in ein frisch erzeugtes Projektarchiv laden mussten. Diese Schemaänderungen haben seit Subversion 1.0 nicht mehr stattgefunden, und die Subversion-Entwickler versprechen, dass die Anwender zwischen Unterversionen von Subversion (wie etwa von 1.3 nach 1.4) keine Abzüge ihrer Projektarchive machen und neu laden müssen. Jedoch gibt es noch andere Gründe, die es erforderlich machen, zu denen Dinge gehören wie das erneute Aufsetzen eines Berkeley-DB-Projektarchivs auf einem neuen Betriebssystem oder einer CPU-Architektur, der Wechsel von einem Berkeley-DB-basierten auf ein FSFS-basiertes Projektarchiv oder (was wir später in diesem Kapitel in „Filtern der Projektarchiv-Historie“ behandeln werden) das Entfernen versionierter Daten aus der Projektarchiv-Historie.

[Anmerkung] Anmerkung

Das Auszugsformat eines Subversion Projektarchivs beschreibt nur versionierte Änderungen. Es beinhaltet keine Informationen über unvollendete Transaktionen, von Anwendern gesetzte Sperren auf Pfade im Projektarchiv, Anpassungen an Projektarchiv- oder Server-Konfigurationen (inklusive Hook-Skripten) usw.

Das Auszugsformat eines Subversion Projektarchivs erlaubt ebenfalls die Umwandlung aus einem vollständig unterschiedlichen Speichermechanismus oder Versions-Kontroll-System. Da das Format der Auszugsdatei größtenteils menschenlesbar ist, sollte es relativ einfach sein, in diesem Dateiformat generische Änderungsmengen zu beschreiben, wobei jede als neue Revision behandelt werden sollte. Tatsächlich verwendet das Werkzeug cvs2svn (siehe „Ein Projektarchiv von CVS nach Subversion überführen“) das Auszugsformat, um den Inhalt eines CVS Projektarchivs zu repräsentieren, so dass dieser Inhalt in ein Subversion Projektarchiv kopiert werden kann.

Momentan beschäftigen wir uns lediglich mit der Migration von Projektarchiv-Daten zwischen Subversion Projektarchiven, die wir detailliert in den folgenden Abschnitten beschreiben werden.

Repository data migration using svnadmin

Welche Gründe für den Umzug der Projektarchiv-Historie für Sie auch immer eine Rolle spielen, die Verwendung der Unterbefehle svnadmin dump und svnadmin load sind der direkte Weg. svnadmin dump gibt ein Intervall von Projektarchiv-Revisionen im speziellen Subversion-Auszugsformat aus. Der Auszug wird zur Standardausgabe geschrieben, während Mitteilungen an die Standardfehlerausgabe gehen. Das erlaubt Ihnen, den Ausgabestrom in eine Datei umzuleiten, während Sie Statusausgaben im Terminalfenster verfolgen können. Zum Beispiel:

$ svnlook youngest myrepos
26
$ svnadmin dump myrepos > dumpfile
* Revision 0 ausgegeben.
* Revision 1 ausgegeben.
* Revision 2 ausgegeben.
…
* Revision 25 ausgegeben.
* Revision 26 ausgegeben.

Am Ende haben Sie eine einzelne Datei (im vorangegangenen Beispiel dumpfile), die alle im Projektarchiv gespeicherten Daten aus dem gewählten Intervall von Revisionen beinhaltet. Beachten Sie, dass svnadmin dump wie jeder andere lesende Prozess (z.B. svn checkout) Revisionsbäume aus dem Projektarchiv liest, so dass Sie diesen Befehl jederzeit aufrufen können.

Der andere Unterbefehl dieses Paars, svnadmin load, liest den Standardeingabestrom als eine Subversion-Projektarchiv-Auszugsdatei und spielt diese Revisionen aus dem Auszug gewissermaßen neu in das Ziel-Projektarchiv. Auch dieser Befehl erzeugt Meldungen, dieses Mal aber über die Standardausgabe:

$ svnadmin load newrepos < dumpfile
<<< Neue Transaktion basierend auf Originalrevision 1 gestartet
     * Füge Pfad hinzu: A ... erledigt.
     * Füge Pfad hinzu: A/B ... erledigt.
     …
------- Neue Revision 1 übertragen (geladen aus Original 1) >>>

<<< Neue Transaktion basierend auf Originalrevision 2 gestartet
     * Bearbeite Pfad: A/mu ... erledigt.
     * Bearbeite Pfad: A/D/G/rho ... erledigt.

------- Neue Revision 2 übertragen (geladen aus Original 2) >>>

…

<<< Neue Transaktion basierend auf Originalrevision 25 gestartet
     * Bearbeite Pfad: A/D/gamma ... erledigt.

------- Neue Revision 25 übertragen (geladen aus Original 25) >>>

<<< Neue Transaktion basierend auf Originalrevision 26 gestartet
     * Füge Pfad hinzu: A/Z/zeta ... erledigt.
     * Bearbeite Pfad: A/mu ... erledigt.

------- Neue Revision 26 übertragen (geladen aus Original 26) >>>

Das Ergebnis eines Ladevorgangs sind neue Revisionen, die dem Projektarchiv hinzugefügt wurden – dasselbe, was Sie erhalten, wenn Sie mit einem normalen Subversion-Client Übergaben an das Projektarchiv machen. Ebenso wie bei einer Übergabe können können Sie Hook-Programme verwenden, um Aktionen vor und nach jeder Übergabe während des Ladevorgangs auszuführen. Indem Sie die Optionen --use-pre-commit-hook und --use-post-commit-hook an svnadmin load übergeben, können Sie Subversion befehlen, für jede zu ladende Revision die Hook-Programme pre-commit bzw. post-commit auszuführen. Sie könnten diese beispielsweise verwenden, um sicherzustellen, dass die geladenen Revisionen dieselben Validierungsschritte durchlaufen müssen wie reguläre Übergaben. Natürlich sollten Sie diese Optionen mit Sorgfalt verwenden – wenn Ihr post-commit-Hook für jede neue Übergabe E-Mails an eine Mailing-Liste verschickt, wollen Sie bestimmt nicht, das innerhalb kürzester Zeit hunderte oder tausende Übergabe-E-Mails in diese Liste hineinhageln! Sie können mehr über Hook-Skripte in „Erstellen von Projektarchiv-Hooks“ lesen.

Beachten Sie, dass Menschen, die sich besonders gewitzt fühlen, weil svnadmin für den Auszug und den Ladevorgang den Standardeingabe- und den Standardausgabestrom benutzt, Dinge wie dieses ausprobieren können (vielleicht sogar unterschiedliche Versionen von svnadmin auf jeder Seite der Pipe):

$ svnadmin create newrepos
$ svnadmin dump oldrepos | svnadmin load newrepos

Im Normalfall wird die Auszugsdatei ziemlich groß – viel größer als das Projektarchiv selbst. Das liegt daran, dass standardmäßig jede Version jeder Datei als vollständiger Text in der Auszugsdatei dargestellt wird. Dies ist das schnellste und einfachste Verhalten, und es ist nett, wenn Sie die Auszugsdaten über eine Pipe direkt an einen weiteren Prozess weiterleiten (etwa ein Komprimierprogramm, ein Filterprogramm oder einen Prozess zum Laden). Wenn Sie jedoch eine Auszugsdatei für die Langzeitspeicherung erzeugen, möchten Sie wahrscheinlich Plattenplatz sparen, indem Sie die Option --deltas verwenden. Mit dieser Option werden aufeinanderfolgende Revisionen von Dateien als komprimierte binäre Unterschiede ausgegeben – so wie Dateirevisionen im Projektarchiv gespeichert werden. Diese Option ist langsamer, führt jedoch zu einer Größe der Auszugsdatei, die der Größe des Original-Projektarchivs näher kommt.

Wir haben eben erwähnt, dass svnadmin dump einen Bereich von Revisionen ausgibt. Verwenden Sie die Option --revision (-r), um eine einzelne Revision oder einen Bereich von Revisionen für den Auszug anzugeben. Wenn Sie diese Option weglassen, wird ein Auszug aller Projektarchiv-Revisionen erstellt.

$ svnadmin dump myrepos -r 23 > rev-23.dumpfile
$ svnadmin dump myrepos -r 100:200 > revs-100-200.dumpfile

Beim Erstellen eines Auszugs jeder Revision gibt Subversion gerade soviel Information aus, dass später ein Ladeprozess in der Lage ist, diese Revision auf der Basis der Vorgängerrevision wiederherzustellen. Mit anderen Worten: Für jede Revision befinden sich nur die Dinge in der Auszugsdatei, die sich in dieser Revision geändert haben. Die einzige Ausnahme von dieser Regel ist die erste Revision, die mit dem aktuellen svnadmin dump erstellt wird.

Standardmäßig wird Subversion den Auszug der ersten Revision nicht bloß als Unterschied ausdrücken, der auf die Vorgängerrevision anzuwenden ist. Zum Ersten gibt es keine Vorgängerrevision in der Auszugsdatei. Und zum Zweiten kann Subversion den Zustand des Projektarchivs, in das der Auszug (falls überhaupt) geladen werden soll, nicht kennen. Um sicherzustellen, dass die Ausgabe jedes Aufrufs von svnadmin dump unabhängig ist, ist der Auszug der ersten Revision standardmäßig eine vollständige Darstellung jedes Verzeichnisses, jeder Datei und jeder Eigenschaft aus dieser Revision im Projektarchiv.

Sie können dieses Standardverhalten jedoch ändern. Falls Sie die Option --incremental angeben, vergleicht svnadmin die erste Revision für die ein Auszug erstellt werden soll mit der vorhergehenden Revision im Projektarchiv – auf dieselbe Art und Weise, wie jede andere Revision behandelt wird, für die ein Auszug erstellt werden soll – indem lediglich die Änderungen aus dieser Revision erwähnt werden. Der Vorteil dabei ist, dass Sie mehrere kleinere Auszugsdateien erstellen können, die hintereinander geladen werden können, anstatt eine große:

$ svnadmin dump myrepos -r 0:1000 > dumpfile1
$ svnadmin dump myrepos -r 1001:2000 --incremental > dumpfile2
$ svnadmin dump myrepos -r 2001:3000 --incremental > dumpfile3

Diese Auszugsdateien können mit der folgenden Befehlsfolge in ein neues Projektarchiv geladen werden:

$ svnadmin load newrepos < dumpfile1
$ svnadmin load newrepos < dumpfile2
$ svnadmin load newrepos < dumpfile3

Ein weiterer toller Trick, den Sie mit der Option --incremental anwenden können besteht darin, einen neuen Bereich von Revisionsauszügen an eine existierende Revisionsdatei anzuhängen. Beispielsweise könnten Sie einen post-commit-Hook haben, der der Datei einen Auszug derjenigen Revision anfügt, die den Hook ausgelöst hat. Oder Sie haben ein Skript, das jede Nacht läuft, um Auszüge sämtlicher Revisionen seit dem letzten Lauf anzufügen. Wenn es auf diese Weise verwendet wird, stellt svnadmin dump eine Möglichkeit dar, laufend die Änderungen an Ihrem Projektarchiv für den Fall eines Systemabsturzes oder eines anderen katastrophalen Ereignisses zu sichern.

Das Auszugsformat kann auch dazu verwendet werden, um die Inhalte mehrerer verschiedener Projektarchive in ein Projektarchiv zusammenzuführen. Indem Sie die Option --parent-dir von svnadmin load benutzen, können Sie ein neues virtuelles Wurzelverzeichnis für den Ladevorgang angeben. Das heißt, falls Sie beispielsweise die Auszugsdateien von drei Projektarchiven haben – etwa calc-dumpfile, cal-dumpfile und ss-dumpfile – können Sie zunächst ein Projektarchiv anlegen, das alle beherbergt:

$ svnadmin create /var/svn/projects
$

Erstellen Sie dann neue Verzeichnisse im Projektarchiv, die den Inhalt der vorherigen drei Projektarchive aufnehmen werden:

$ svn mkdir -m "Initial project roots" \
            file:///var/svn/projects/calc \
            file:///var/svn/projects/calendar \
            file:///var/svn/projects/spreadsheet 
Revision 1 übertragen.
$ 

Laden Sie schließlich die Auszugsdateien an ihren jeweiligen Ort im neuen Projektarchiv:

$ svnadmin load /var/svn/projects --parent-dir calc < calc-dumpfile
…
$ svnadmin load /var/svn/projects --parent-dir calendar < cal-dumpfile
…
$ svnadmin load /var/svn/projects --parent-dir spreadsheet < ss-dumpfile
…
$

Projektarchiv-Daten-Migration mit svnrdump

In Subversion 1.7 kam svnrdump zu der Menge von mitgelieferten Subversion-Werkzeugen hinzu. Es bietet eine ziemlich spezialisierte Funktionalität, im Wesentlichen als netzwerkfähige Version der Befehle svnadmin dump und svnadmin load, die wir im Detail in „Repository data migration using svnadmin“ erörtern. svnrdump dump erzeugt einen Auszugsstrom eines Fern-Projektarchivs und schreibt ihn in den Standard-Ausgabekanal; svnrdump load liest einen Auszugsstrom aus dem Standard-Eingabekanal und lädt ihn in ein Fern-Projektarchiv. Mit svnrdump können Sie inkrementelle Auszüge erstellen, wie mit svnadmin dump. Sie können sogar einen Auszug eines Teilbaums des Projektarchivs erstellen, was svnadmin dump nicht kann.

Der Hauptunterschied besteht darin, dass svnrdump ohne einen Direktzugriff auf das Projektarchiv zu benötigen, aus der Ferne arbeitet, wobei es die selben Repository Access (RA) Protokolle verwendet wie der Subversion-Client. Daher kann es sein, dass Sie Authentifizierungs-Informationen bereitstellen müssen. Darüber hinaus unterliegen Ihre Aktionen aus der Ferne den konfigurierten Autorisierungs-Einschränkungen des Subversion-Servers.

[Anmerkung] Anmerkung

svnrdump dump erfordert einen Fern-Server mit Subversion 1.4 oder neuer. Gegenwärtig erzeugt es nur Auszugsströme der Art wie Sie sie bekommen, wenn Sie svnadmin dump die Option --deltas mitgeben. In den typischen Anwendungsfällen ist das nicht von Interesse, jedoch kann es Auswirkungen auf bestimmte Arten besonderer Transformationen haben, die Sie auf den Auszugsstrom anwenden möchten.

[Anmerkung] Anmerkung

Da es nach der Übergabe neuer Revisionen die Revisions-Eigenschaften ändert, verlangt svnrdump load, dass im Ziel-Projektarchiv Änderungen an Revisions-Eigenschaften mittels des Hooks pre-revprop-change ermöglicht sind. Zu Details, siehe pre-revprop-change in Subversion Projektarchiv-Hook-Referenz.

Wie Sie wohl erwartet haben, können Sie svnadmin und svnrdump in Verbindung verwenden. Sie können beispielsweise svnrdump dump verwenden, um einen Auszugsstrom eines Fern-Projektarchivs zu erstellen und das Ergebnis an svnadmin load weiterleiten, um die Historie jenes Projektarchivs in das lokale Projektarchiv zu kopieren. Oder Sie können im Gegenzug die Historie eines lokalen Projektarchivs in ein fernes kopieren.

[Tipp] Tipp

Durch die Verwendung von file:// URLs kann svnrdump auch auf lokale Projektarchive zugreifen, allerdings wird hierfür auf Subversions Abstraktionsebene Repository Access (RA) zugegriffen; mit svnadmin ist in solchen Fällen der Durchsatz besser.

Filtern der Projektarchiv-Historie

Da Subversion Ihre versionierte Historie mindestens mit binären Differenz-Algorithmen und Datenkompression abspeichert (optional in einem völlig undurchsichtigen Datenbanksystem), ist der Versuch manueller Eingriffe unklug, zumindest schwierig und unter allen Umständen nicht angeraten. Sobald Daten im Projektarchiv gespeichert sind, bietet Subversion im Allgemeinen keine einfache Möglichkeit, diese Daten zu entfernen.[55] Doch zwangsläufig werden sich Gelegenheiten ergeben, bei denen Sie die Historie Ihres Projektarchivs manipulieren müssen. Es könnte sein, dass Sie alle Instanzen einer Datei entfernen müssen, die versehentlich dem Projektarchiv hinzugefügt worden ist, aber aus welchen Gründen auch immer nicht hineingehört). [56] Oder Sie haben vielleicht mehrere Projekte, die sich ein Projektarchiv teilen und entscheiden sich nun, jedem Projekt sein eigenes Projektarchiv zu geben. Um Aufgaben wie diese bewerkstelligen zu können, benötigen Administratoren eine besser handhabbare und bearbeitbare Repräsentation der Daten in den Projektarchiven – das Subversion-Projektarchiv-Auszugsformat.

Wie bereits in „Projektarchiv-Daten woanders hin verschieben“ beschrieben, ist das Subversion-Projektarchiv-Auszugsformat eine menschenlesbare Wiedergabe der Änderungen, die Sie an Ihren versionierten Daten im Laufe der Zeit vorgenommen haben. Verwenden Sie den Befehl svnadmin dump oder svnrdump dump, um den Auszug anzulegen und svnadmin load oder svnrdump load, um ein neues Projektarchiv damit zu füllen. Das Tolle an der Menschenlesbarkeit des Auszugsformates ist, dass Sie, sofern es Ihnen nicht egal ist, die Daten manuell untersuchen und verändern können. Natürlich besteht ein Nachteil darin, dass eine Auszugsdatei eines Projektarchivs, in das über drei Jahre Änderungen eingeflossen sind, riesig groß sein wird, und es Sie eine lange, lange Zeit kosten wird, die Daten manuell zu untersuchen und zu verändern.

Hierbei hilft svndumpfilter. Dieses Programm verhält sich wie ein pfadbasierter Filter für Auszugsströme. Geben Sie ihm einfach eine Liste von Pfaden mit, die Sie behalten möchten oder eine Liste von Pfaden, die Sie nicht behalten möchten, und leiten Sie Ihre Auszugsdaten durch diesen Filter. Das Ergebnis ist ein modifizierter Strom der Auszugsdaten, der nur die versionierten Pfade beinhaltet, die Sie (explizit oder implizit) verlangt haben.

Lassen Sie uns an einem realistischen Beispiel betrachten, wie Sie diesen Programm verwenden könnten. Früher in diesem Kapitel (siehe „Planung der Organisation Ihres Projektarchivs“) erörterten wir das Entscheidungsfindungsverfahren, wie Sie Ihre Daten im Projektarchiv anordnen sollen – ein Projektarchiv pro Projekt oder kombiniert, wie Sie die Daten im Projektarchiv verteilen usw. Doch manchmal, nachdem bereits einige Revisionen hinzugekommen sind, überdenken Sie die Anordnung und würden gerne einige Änderungen vornehmen. Eine verbreitete Änderung ist die Entscheidung, mehrere Projekte, die sich ein Projektarchiv teilen, auf getrennte Projektarchive pro Projekt aufzuteilen.

Unser imaginäres Projektarchiv beinhaltet drei Projekte: calc, calendar und spreadsheet. Sie waren miteinander in der folgenden Anordnung abgelegt:


/
   calc/
      trunk/
      branches/
      tags/
   calendar/
      trunk/
      branches/
      tags/
   spreadsheet/
      trunk/
      branches/
      tags/

Um diese drei Projekte in ihre eigenen Projektarchive zu bekommen, erstellen wir zunächst einen Auszug des gesamten Projektarchivs:

$ svnadmin dump /var/svn/repos > repos-dumpfile
* Revision 0 ausgegeben.
* Revision 1 ausgegeben.
* Revision 2 ausgegeben.
* Revision 3 ausgegeben.
…
$

Dann leiten wir die Auszugsdatei durch die Filter, wobei jedes Mal nur jeweils eins der obersten Verzeichnisse ausgewählt wird. Als Ergebnis erhalten wir drei Auszugsdateien:

$ svndumpfilter include calc < repos-dumpfile > calc-dumpfile
…
$ svndumpfilter include calendar < repos-dumpfile > cal-dumpfile
…
$ svndumpfilter include spreadsheet < repos-dumpfile > ss-dumpfile
…
$

An dieser Stelle müssen sie eine Entscheidung treffen. Jede Ihrer Auszugsdateien wird ein gültiges Projektarchiv erzeugen, allerdings unter Beibehaltung der Pfade wie sie im ursprünglichen Projektarchiv waren. Das bedeutet, dass, obwohl Sie ein Projektarchiv ausschließlich für Ihr calc Projekt haben, wird es immer noch ein Wurzelverzeichnis namens calc besitzen. Falls Sie möchten, dass die Verzeichnisse trunk, tags und branches direkt im Wurzelverzeichnis Ihres Projektarchivs liegen, sollten Sie Ihre Auszugsdateien editieren, indem Sie die Einträge Node-path und Node-copyfrom-path verändern, so dass sie nicht mehr die erste Komponente calc/ im Pfad haben. Sie sollten auch den Abschnitt entfernen, der das Verzeichnis calc anlegt. Es sollte etwa wie folgt aussehen:

Node-path: calc
Node-action: add
Node-kind: dir
Content-length: 0
  
[Warnung] Warnung

Falls Sie sich entscheiden sollten, die Auszugsdatei manuell zu editieren, um eins der obersten Verzeichnisse zu entfernen, sollten Sie sicherstellen, dass Ihr Editor nicht automatisch Zeilenenden in das native Format umwandelt (z.B. \r\n in \n), da sonst der Inhalt nicht zu den Metadaten passt. Das würde Ihre Auszugsdatei nutzlos machen.

Alles, was jetzt noch übrig bleibt, ist, Ihre drei neuen Projektarchive zu erstellen und jede Auszugsdatei in das richtige Projektarchiv zu laden, wobei die UUID aus dem Auszugsstrom ignoriert wird:

$ svnadmin create calc
$ svnadmin load --ignore-uuid calc < calc-dumpfile
<<< Neue Transaktion basierend auf Originalrevision 1 gestartet
     * Füge Pfad hinzu: Makefile ... erledigt.
     * Füge Pfad hinzu: button.c ... erledigt.
…
$ svnadmin create calendar
$ svnadmin load --ignore-uuid calendar < cal-dumpfile
<<< Neue Transaktion basierend auf Originalrevision 1 gestartet
     * Füge Pfad hinzu: Makefile ... erledigt.
     * Füge Pfad hinzu: cal.c ... erledigt.
…
$ svnadmin create spreadsheet
$ svnadmin load --ignore-uuid spreadsheet < ss-dumpfile
<<< Neue Transaktion basierend auf Originalrevision 1 gestartet
     * Füge Pfad hinzu: Makefile ... erledigt.
     * Füge Pfad hinzu: ss.c ... erledigt.
…
$

Beide Unterbefehle von svndumpfilter akzeptieren Optionen, die angeben, wie leere Revisionen behandelt werden sollen. Falls eine Revision nur Änderungen an herausgefilterten Pfaden beinhaltet, könnte die neue Revision als uninteressant oder gar unerwünscht gelten. Um dem Anwender die Kontrolle darüber zu geben, wie hiermit verfahren werden soll, bietet svndumpfilter die folgenden Kommandozeilen-Optionen:

--drop-empty-revs

Überhaupt keine leeren Revisionen erzeugen – einfach auslassen.

--renumber-revs

Falls leere Revisionen ausgelassen werden (mit der Option --drop-empty-revs), die Nummern der übrig gebliebenen Revisionen ändern, so dass keine Lücken in der Nummernfolge auftreten.

--preserve-revprops

Falls leere Revisionen nicht ausgelassen werden, die Eigenschaften der leeren Revisionen bewahren (Protokolleintrag, Autor, Datum, Eigenschaften usw.). Sonst beinhalten leere Revisionen lediglich den Zeitstempel und einen erzeugten Protokolleintrag, der darauf hinweist, dass diese Revision von svndumpfilter geleert wurde.

Obwohl svndumpfilter sehr nützlich und eine Zeitersparnis sein kann, gibt es unglücklicherweise ein paar Fallstricke. Erstens ist das Dienstprogramm überempfindlich gegenüber der Pfadsemantik. Achten Sie darauf, ob die Pfade in Ihrer Auszugsdatei mit oder ohne führende Schrägstriche angegeben werden. Sie sollten sich die Einträge Node-path und Node-copyfrom-path ansehen.

…
Node-path: spreadsheet/Makefile
…

Falls die Pfade führende Schrägstriche haben, sollten auch Sie Schrägstriche in den Pfaden angeben, die Sie an svndumpfilter include und svndumpfilter exclude übergeben (und wenn sie keine haben, sollten Sie auch keine angeben). Falls Ihre Auszugsdatei aus irgendwelchen Gründen einen nicht konsistenten Gebrauch von führenden Schrägstrichen macht, [57] sollten Sie diese Pfade normalisieren, so dass sie alle entweder Schrägstriche haben oder nicht.

Ebenso können kopierte Pfade Probleme bereiten. Subversion unterstützt Kopieroperationen im Projektarchiv, bei denen ein neuer Pfad erzeugt wird, indem ein bereits bestehender kopiert wird. Es kann vorkommen, dass Sie zu irgendeinem Zeitpunkt der Lebenszeit Ihres Projektarchivs eine Datei oder ein Verzeichnis von einer durch svndumpfilter ausgelassenen Stelle an eine durch svndumpfilter berücksichtigte Stelle kopiert haben. Um die Auszugsdateien unabhängig zu machen, muss svndumpfilter trotzdem das Hinzufügen des neuen Pfades anzeigen – mit dem Inhalt aller durch die Kopie erzeugten Dateien – allerdings nicht als eine Kopie aus einer Quelle, die es gar nicht im gefilterten Auszugsstrom gibt. Da allerdings das Subversion Auszugsdateiformat nur Änderungen von Revisionen beinhaltet, kann es sein, dass der Inhalt der Quelle der Kopie nicht verfügbar ist. Wenn Sie mutmaßen, dass Sie solche Kopien in Ihrem Projektarchiv haben, sollten Sie die Auswahl der ausgelassenen/berücksichtigten Pfade überdenken, indem Sie vielleicht die Pfade, die als Quellen für die problematischen Kopien dienten, hinzunehmen.

Schließlich behandelt svndumpfilter Pfadfilterung ziemlich wörtlich. Wenn Sie die Historie eines Projektes mit dem Wurzelverzeichnis trunk/my-project kopieren und sie in ein eigenes Projektarchiv verschieben möchten, werden Sie selbstverständlich den Befehl svndumpfilter include verwenden, um alle Änderungen in und unterhalb von trunk/my-project zu bewahren. Doch macht die entstehende Auszugsdatei keinerlei Annahmen bezüglich des Projektarchivs, in das Sie die Daten zu laden beabsichtigen. In diesem besonderen Fall könnten die Auszugsdaten mit der Revision beginnen, die das Verzeichnis trunk/my-project hinzugefügt hat, doch sie werden keine Direktiven enthalten, dir das Verzeichnis trunk selbst anlegen (weil trunk nicht zum Filter der zu berücksichtigenden Pfade passt). Sie müssen sicherstellen, dass alle Verzeichnisse, die der Auszugsstrom erwartet, tatsächlich im Ziel-Projektarchiv vorhanden sind, bevor Sie versuchen, den Strom in dieses Projektarchiv zu laden.

Projektarchiv Replikation

Es gibt mehrere Szenarien, in denen es sehr passend ist, ein Subversion-Projektarchiv zu haben, dessen Versionshistorie genau dieselbe wie die eines anderen Projektarchivs ist. Vielleicht das offensichtlichste ist die Aufrechterhaltung eines Projektarchivs als einfache Sicherheitskopie, das verwendet wird, wenn das primäre Projektarchiv wegen Materialdefekt, Netzausfall oder ähnlichen Ärgernissen unzugänglich geworden ist. Andere Szenarien umfassen den Einsatz von Spiegel-Projektarchiven, um heftige Subversion-Last über mehrere Server zu verteilen, zum sanften Aufrüsten usw.

Subversion stellt ein Programm zur Handhabung solcher Szenarien zur Verfügung. Im Wesentlichen funktioniert svnsync, indem der Subversion-Server aufgefordert wird, Revisionen zu wiederholen, eine nach der anderen. Dann wird die Information dieser Revision benutzt, um eine Übergabe derselben an ein anderes Projektarchiv zu imitieren. Keins der Projektarchive muss lokal auf der Maschine liegen, auf der svnsync läuft – seine Parameter sind Projektarchiv-URLs, und es verrichtet seine gesamte Arbeit über die Projektarchiv-Access-Schnittstellen (RA) von Subversion. Das Einzige, was benötigt wird, ist Lesezugriff auf das Quell-Projektarchiv und Lese-/Schreibzugriff auf das Ziel-Projektarchiv.

[Anmerkung] Anmerkung

Wenn Sie svnsync mit einem entfernt liegenden Quell-Projektarchiv verwenden, muss auf dem Subversion-Server für dieses Projektarchiv Subversion 1.4 oder neuer laufen.

Replizierung mit svnsync

Angenommen, Sie haben bereits ein Projektarchiv, das Sie gerne spiegeln möchten. Als nächstes brauchen Sie ein leeres Ziel-Projektarchiv, das als Spiegel dienen soll. Dieses Projektarchiv kann irgendeins der verfügbaren Speicherverfahren benutzen (siehe Speaking of Filesystems…) – die Abstraktionsschichten von Subversion stellen sicher, dass solche Details unerheblich sind. Doch standardmäßig darf es noch keine Versionshistorie enthalten. (Eine Ausnahme davon werden wir später in diesem Abschnitt erörtern.)

Das von svnsync verwendete Protokoll zur Übermittlung der Revisionsinformation ist sehr empfindlich gegenüber nicht übereinstimmender Versionshistorien im Quell- und Ziel-Projektarchiv. Aus dem Grund, dass svnsync nicht verlangen kann, dass das Ziel-Projektarchiv nur lesbar ist,[58] ist die Katastrophe programmiert, wenn erlaubt wird, die Revisions-Historie im Ziel-Projektarchiv mit anderen Mitteln als durch das Spiegeln zu verändern.

[Warnung] Warnung

Verändern Sie ein Spiegel-Projektarchiv nicht auf eine Art und Weise, die dazu führt, dass die Versionshistorie von der des Original-Projektarchivs abweicht. Die einzigen Übergaben und Änderungen an Revisions-Eigenschaften die in diesem Spiegel-Projektarchiv stattfinden, sollten ausschließlich durch den Befehl svnsync vorgenommen werden.

Eine weitere Anforderung an das Ziel-Projektarchiv ist, dass dem svnsync-Prozess erlaubt wird, Revisions-Eigenschaften zu verändern. Da svnsync im Rahmen des Hook-Systems ausgeführt wird, ist der standardmäßige Zustand des Projektarchivs (welcher keine Änderungen an Revisions-Eigenschaften zulässt; siehe pre-revprop-change in Subversion Projektarchiv-Hook-Referenz) nicht ausreichend. Sie müssen ausdrücklich den pre-revprop-change-Hook bereitstellen, der svnsync erlaubt, Revisions-Eigenschaften zu definieren und zu ändern. Mit diesen Vorkehrungen sind Sie gerüstet, um Projektarchiv-Revisionen zu spiegeln.

[Tipp] Tipp

Es ist eine gute Idee, Autorisierungsmaßnahmen zu ergreifen, um Ihrem Projektarchiv-Replikations-Prozess die Arbeit zu ermöglichen, wohingegen anderen Anwendern die Veränderung der Inhalte des Spiegel-Projektarchivs verwehrt wird.

Lassen Sie uns nun die Benutzung von svnsync bei einem Rundgang in einem typischen Spiegel-Szenario erklären. Wir werden diesen Diskurs mit Empfehlungen würzen, die Sie jedoch getrost missachten können, falls sie für Ihre Umgebung nicht benötigt werden oder nicht passend sind.

Wir wollen das öffentliche Subversion-Projektarchiv spiegeln, das den Quelltext des vorliegenden Buchs beherbergt, und diesen Spiegel von einer anderen Maschine als der, auf der das ursprüngliche Subversion-Quelltext-Projektarchiv untergebracht ist, im Internet veröffentlichen. Dieser entfernt liegende Rechner besitzt eine globale Konfiguration, die es anonymen Anwendern erlaubt, den Inhalt von Projektarchivs auf diesem Rechner zu lesen, aber zum Ändern dieser Projektarchive eine Authentifizierung der Anwender erforderlich macht. (Vergeben Sie uns bitte, dass wir für den Augenblick über die Details der Subversion-Server-Konfiguration hinwegsehen – sie werden in Kapitel 6, Konfiguration des Servers behandelt.) Und aus dem alleinigen Grund, es noch interessanter machen zu wollen, werden wir den Replikations-Prozess von einer dritten Maschine aus steuern – diejenige, die wir aktuell benutzen.

Zunächst erstellen wir das Projektarchiv, das unser Spiegel sein soll. Dieser und die folgenden paar Schritte erfordern einen Shell-Zugang auf die Maschine, die das Spiegel-Projektarchiv beherbergen soll. Sobald das Projektarchiv jedoch konfiguriert ist, sollten wir nicht mehr direkt darauf zugreifen müssen.

$ ssh admin@svn.example.com "svnadmin create /var/svn/svn-mirror"
admin@svn.example.com's password: ********
$

Zu diesem Zeitpunkt haben wir unser Projektarchiv, und wegen unserer Server-Konfiguration ist das Projektarchiv nun live im Internet. Da wir aber außer unserem Replikations-Prozess niemanden erlauben wollen, das Projektarchiv zu ändern, benötigen wir eine Möglichkeit, diesen Prozess von anderen potentiellen Zugriffen zu unterscheiden. Um dies zu machen, verwenden wir einen ausgezeichneten Anwendernamen für unseren Prozess. Nur Übergaben und Änderungen an Revisions-Eigenschaften unter dem Anwenderkonto syncuser werden erlaubt.

Wir verwenden das Hook-System des Projektarchivs sowohl, um dem Replikations-Prozess seine Arbeit zu ermöglichen, als auch, um sicherzustellen, dass nur er diese Dinge tut. Wir bewerkstelligen dies, indem wir zwei der Projektarchiv-Ereignis-Hooks implementieren – pre-revprop-change und start-commit. Unser pre-revprop-change-Hook-Skript finden Sie in Beispiel 5.4, „pre-revprop-change-Hook-Skript des Spiegel-Projektarchivs“; grundsätzlich stellt es sicher, dass der Anwender, der die Eigenschaften ändern möchte, unser syncuser ist. Falls dies zutrifft, ist die Änderung erlaubt, anderenfalls wird die Änderung abgelehnt.

Beispiel 5.4. pre-revprop-change-Hook-Skript des Spiegel-Projektarchivs

#!/bin/sh 

USER="$3"

if [ "$USER" = "syncuser" ]; then exit 0; fi

echo "Ausschließlich der Anwender syncuser darf Revisions-Eigenschaften ändern" >&2
exit 1

Das deckt Änderungen an Revisions-Eigenschaften ab. Nun müssen wir sicherstellen, dass nur der Anwender syncuser neue Revisionen an das Projektarchiv übertragen darf. Wir machen das, indem wir ein start-commit-Hook-Skript wie das in Beispiel 5.5, „start-commit-Hook-Skript des Spiegel-Projektarchivs“ benutzen.

Beispiel 5.5. start-commit-Hook-Skript des Spiegel-Projektarchivs

#!/bin/sh 

USER="$2"

if [ "$USER" = "syncuser" ]; then exit 0; fi

echo "Ausschließlich der Anwender syncuser darf neue Revisionen übertragen" >&2
exit 1

Nachdem wir unsere Hook-Skripte installiert und uns vergewissert haben, dass sie auf dem Subversion-Server ausführbar sind, sind wir mit dem Aufsetzen des Spiegel-Projektarchivs fertig. Nun kommen wir zum eigentlichen Spiegeln.

Das Erste, was wir machen müssen ist, unserem Ziel-Projektarchiv mit svnsync zu sagen, dass es ein Spiegel des Quell-Projektarchivs sein wird. Wir machen das mit dem Unterbefehl svnsync initialize. Die URLs, die wir mitgeben, zeigen auf die Wurzelverzeichnisse des Ziel- bzw. Quell-Projektarchivs. In Subversion 1.4 ist das erforderlich – nur die vollständige Spiegelung von Projektarchiven ist erlaubt. Beginnend mit Subversion 1.5 jedoch können Sie svnsync auch zum Spiegeln von Teilbäumen des Projektarchivs verwenden.

$ svnsync help init
initialize (init): Aufruf: svnsync initialize ZIEL_URL QUELL_URL

Bereitet ein Zielprojektarchiv auf die Synchronisation mit einem
anderen Projektarchiv vor.
…
$ svnsync initialize http://svn.example.com/svn-mirror \
                     https://svn.code.sf.net/p/svnbook/source \
                     --sync-username syncuser --sync-password syncpass
Eigenschaften für Revision 0 kopiert (svn:sync-* Eigenschaften übergangen).
HINWEIS: svn:* Eigenschaften nach LF-Zeilenenden normalisiert (1 Revisionseigenschaften, 0 Knoteneigenschaften).
$

Unser Ziel-Projektarchiv wird sich nun erinnern, dass es ein Spiegel des öffentlichen Subversion-Quelltext-Projektarchivs ist. Beachten Sie, dass wir einen Anwendernamen und ein Passwort an svnsync übergeben haben – das war für den pre-revprop-change-Hook in unserem Spiegel-Projektarchiv erforderlich.

[Anmerkung] Anmerkung

In Subversion 1.4 wurden die an die Kommandozeilenoptionen --username und --password von svnsync übergebenen Werte sowohl für die Authentisierung gegenüber dem Quell-Projektarchiv als auch gegenüber dem Ziel-Projektarchiv verwendet. Das führte zu Problemen, falls die Zugangsdaten eines Anwenders nicht für beide Projektarchive identisch waren, insbesondere im nicht-interaktiven Modus (mit der Option --non-interactive). Dies ist in Subversion 1.5 mit der Einführung von zwei neuen Optionspaaren behoben worden. Benutzen Sie --source-username und --source-password für die Zugangsdaten des Quell-Projektarchivs sowie --sync-username und --sync-password für das Ziel-Projektarchiv. (Die alten Optionen --username und --password bleiben aus Kompatibilitätsgründen bestehen, doch raten wir von deren Verwendung ab.)

Und nun kommt der lustige Teil. Mit einem einfachen Unterbefehl können wir svnsync auffordern, alle bislang ungespiegelten Revisionen aus dem Quell-Projektarchiv zum Ziel zu kopieren.[59] Der Unterbefehl svnsync synchronize wird die bereits vorher im Ziel-Projektarchiv gespeicherten besonderen Revisions-Eigenschaften untersuchen und sowohl ermitteln, welches Projektarchiv es spiegelt und dass die zuletzt gespiegelte Revision die Revision 0 war. Dann fragt es das Quell-Projektarchiv ab, welches die jüngste Revision in diesem Projektarchiv ist. Schließlich fordert es den Server des Quell-Projektarchivs auf, alle Revisionen zwischen 0 und dieser letzten Revision zu wiederholen. Sobald svnsync die entsprechende Antwort vom Quell-Projektarchiv-Server erhält, leitet es diese Revisionen als neue Übergaben an den Server des Ziel-Projektarchivs weiter.

$ svnsync help synchronize
synchronize (sync): Aufruf: svnsync synchronize ZIEL_URL [QUELL_URL]

Überträgt alle laufenden Revisionen von der Quelle, mit der es
initialisiert wurde, zum Ziel.
…
$ svnsync synchronize http://svn.example.com/svn-mirror \
                      https://svn.code.sf.net/p/svnbook/source
Revision 1 übertragen.
Eigenschaften für Revision 1 kopiert.
Revision 2 übertragen.
Eigenschaften für Revision 2 kopiert.
Übertrage Daten .
Revision 3 übertragen.
Eigenschaften für Revision 3 kopiert.
…
Übertrage Daten .
Revision 4063 übertragen.
Eigenschaften für Revision 4063 kopiert.
Übertrage Daten .
Revision 4064 übertragen.
Eigenschaften für Revision 4064 kopiert.
Übertrage Daten .
Revision 4065 übertragen.
Eigenschaften für Revision 4065 kopiert.
$

Von besonderem Interesse ist hier, dass für jede gespiegelte Revision zunächst eine Übergabe der Revision an das Ziel-Projektarchiv erfolgt und dann die Änderungen der Eigenschaften folgen. Diese zweiphasige Replizierung ist notwendig, da die anfängliche Übergabe durch den Anwender syncuser durchgeführt (und ihm auch zugeschrieben) wird und mit dem Zeitstempel der Erzeugung dieser Revision versehen wird. svnsync hat hinterher unmittelbaren Serie von Änderungen an den Eigenschaften vorzunehmen, die all die Eigenschaften dieser Revision vom Quell-Projektarchiv ins Ziel-Projektarchiv kopieren, was auch den Effekt hat, dass der Autor und der Zeitstempel so korrigiert werden, dass diese den entsprechenden Werten im Quell-Projektarchiv entsprechen.

Erwähnenswert ist ebenfalls, dass svnsync eine sorgfältige Buchführung vornimmt, die es ihm erlaubt, sicher unterbrochen und erneut gestartet zu werden, ohne die Integrität der gespiegelten Daten zu gefährden. Falls während des Spiegelns ein Netzproblem entsteht, wiederholen Sie einfach den Befehl svnsync synchronize, und er wird einfach damit weitermachen, womit er aufgehört hat. Das ist tatsächlich genau das, was Sie machen, um Ihren Spiegel aktuell zu halten, wenn neue Revisionen im Quell-Projektarchiv auftauchen.

[Warnung] Warnung

As part of its bookkeeping, svnsync records in the mirror repository the URL with which the mirror was initialized. Because of this, invocations of svnsync which follow the initialization step do not require that you provide the source URL on the command line again. However, for security purposes, we recommend that you continue to do so. Depending on how it is deployed, it may not be safe for svnsync to trust the source URL which it retrieves from the mirror repository, and from which it pulls versioned data.

In diesem Prozess ist jedoch eine kleine Unfeinheit. Da die Revisions-Eigenschaften von Subversion jederzeit während der Lebenszeit eines Projektarchivs geändert werden können, ohne zu protokollieren, wann sie geändert wurden, müssen replizierende Prozesse ein besonderes Augenmerk auf sie richten. Wenn Sie bereits die ersten 15 Revisionen eines Projektarchivs gespiegelt haben, und dann jemand eine Revisions-Eigenschaft von Revision 12 ändert, weiß svnsync nicht, dass es zurückgehen und die Kopie der Revision 12 korrigieren muss. Sie müssen es ihm manuell mitteilen, indem Sie den Unterbefehl svnsync copy-revprops verwenden, der einfach alle Eigenschaften einer bestimmten Revision oder eines Revisionsintervalls erneut repliziert.

$ svnsync help copy-revprops 
copy-revprops: Aufruf:

    1. svnsync copy-revprops ZIEL_URL [QUELL_URL]
    2. svnsync copy-revprops ZIEL_URL PAR1[PAR2]

…
$ svnsync copy-revprops http://svn.example.com/svn-mirror 12 
Eigenschaften für Revision 12 kopiert.
$

Das ist Projektarchiv-Replikation mit svnsync in aller Kürze. Sehr wahrscheinlich möchten Sie einen solchen Prozess etwas automatisieren. Während unser Beispiel ein Ziehen-und-Schieben-Szenario beschrieb, möchten Sie vielleicht, dass Ihr primäres Projektarchiv als Teil der post-commit- und post-revprop-change-Hooks Änderungen an einen oder mehrere ausgesuchte Spiegel weiterschiebt. Das würde es ermöglichen, dass der Spiegel beinahe in Echtzeit aktuell gehalten werden kann.

Teilweise Replizierung mit svnsync

svnsync ist nicht darauf beschränkt, vollständige Kopien des Inhalts von Projektarchiven zu machen. Es kann auch verschiedene Spielarten der teilweisen Replizierung bewerkstelligen. Beispielsweise spiegelt svnsync, wenn dies auch nicht ein häufiger Anwendungsfall ist, Projektarchive, in denen der Anwender unter dessen Kennung es läuft, nur eingeschränkte Rechte besitzt. Es werden dann einfach nur die Teile des Projektarchivs kopiert, die der Anwender sehen darf. Offensichtlich taugt so ein Spiegel nicht als Sicherheitskopie.

Seit Subversion 1.5 hat svnsync auch die Fähigkeit, eine Teilmenge eines Projektarchivs statt des Ganzen zu spiegeln. Das Anlegen und Pflegen eines solchen Spiegels unterscheidet sich nicht vom Spiegeln eines kompletten Projektarchivs; anstatt den Wurzel-URL des Quell-Projektarchivs bei svnsync init anzugeben, nennen Sie einfach den URL eines Unterverzeichnisses dieses Projektarchivs. Hierbei gibt es allerdings einige Einschränkungen. Als Erstes können Sie nicht mehrere disjunkte Unterverzeichnisse des Quell-Projektarchivs in ein einzelnes Ziel-Projektarchiv spiegeln – stattdessen müssen Sie ein Eltern-Verzeichnis spiegeln, das allen gemeinsam ist. Zum Zweiten ist die Filterlogik vollständig pfadbasiert, so dass bei Verzeichnissen, die in der Vergangenheit einmal umbenannt wurden, Ihr Spiegel nur die Revisionen seit dem Zeitpunkt enthält an dem das Verzeichnis unter diesem URL zu finden war. Auch wenn das Unterverzeichnis künftig umbenannt wird, werden Revisionen nur bis zu dem Zeitpunkt gespiegelt, an dem der URL ungültig wird.

Ein schneller Trick zur Spiegel-Erstellung

Vorher erwähnten wir die Kosten der Einrichtung und der initialen Spiegelung eines bestehenden Projektarchivs. Für viele Leute sind die reinen Kosten der Übertragung tausender – oder Millionen von – Revisionen der Historie in ein neues Spiegel-Projektarchiv mit svnsync das KO-Kriterium. Glücklicherweise stellt Subversion 1.7 eine Abhilfe in Form der neuen Option --allow-non-empty für svnsync initialize zur Verfügung. Diese Option erlaubt Ihnen, ein Projektarchiv als Spiegel eines anderen zu initialisieren, wobei die Verifizierung umgangen wird, dass der zu initialisierende Spiegel keine Historie beinhaltet. Durch unsere vorhergehenden Warnungen über die Empfindlichkeit des gesamten Replizierungsprozesses, sollten Sie mit Recht wahrgenommen haben, dass diese Option nur mit großer Vorsicht verwendet werden sollte. Aber sie ist wunderbar praktisch, falls Sie administrativen Zugriff auf das Quell-Projektarchiv haben und einfach eine physikalische Kopie des Projektarchivs erstellen und diese Kopie als einen neuen Spiegel initialisieren können:

$ svnadmin hotcopy /path/to/repos /path/to/mirror-repos 
$ ### /path/to/mirror-repos/hooks/pre-revprop-change anlegen
$ svnsync initialize file:///path/to/mirror-repos \
                     file:///path/to/repos 
svnsync: E000022: Das Zielprojektarchiv enthält schon eine Revisionsgeschichte
. Sie können es mit »--allow-non-empty« versuchen, falls die Revisionen dieses
Projektarchivs denen des Quellprojektarchivs genau entsprechen.
$ svnsync initialize --allow-non-empty file:///path/to/mirror-repos \
                                       file:///path/to/repos 
Eigenschaften für Revision 32042 kopiert.
$

Administratoren, die eine Version von Subversion vor 1.7 betreiben (und deshalb keinen Zugang zur --allow-non-empty-Funktionalität von svnsync initialize haben), können effektiv das selbe erreichen, indem sie sorgfältig die r0-Eigenschaften der Kopie des Projektarchivs manipulieren, dass der Spiegel des Originals werden soll. Verwenden Sie svnadmin setrevprop, um die selben Eigenschaften zur Buchhaltung zu erstellen, die svnsync dort erstellt hätte.

Nachbereitung der Replizierung

Wir erörterten ein paar Möglichkeiten, Revisionsgeschichte vin einem Projektarchiv zu einem anderen zu replizierten. Lassen Sie uns nun aus Anwendersicht auf diese Operationen schauen. Wie wirkt sich Replikation und die verschiedenen Situationen, die sie erforderlich machen auf die Subversion-Clients aus?

Was das Zusammenspiel von Anwendern mit Projektarchiven und Spiegeln betrifft, ist es möglich eine einzelne Arbeitskopie zu haben, die mit beiden kommuniziert, doch müssen Sie hierfür einige Verrenkungen machen. Zunächst müssen Sie sicherstellen, dass sowohl das primäre Projektarchiv als auch das Spiegel-Projektarchiv dieselbe Projektarchiv-UUID haben (was standardmäßig nicht der Fall ist). Mehr darüber unter „Verwaltung von Projektarchiv UUIDs“ später in diesem Kapitel.

Sobald beide Projektarchive dieselbe UUID haben, können Sie svn relocate benutzen, um das Projektarchiv auszuwählen, mit dem Sie arbeiten wollen; dieser Prozess ist in svn relocate in svn Referenz – Subversion-Kommandozeilen-Client beschrieben. Eine mögliche Gefahr besteht allerdings, wenn das Haupt- und das Spiegel-Projektarchiv nicht zeitnah synchronisiert sind. Eine Arbeitskopie, die auf das Haupt-Projektarchiv zeigt und gegenüber diesem aktuell ist, wird nach dem Umschalten auf den nicht aktuellen Spiegel durch den plötzlichen Verlust von Revisionen, die sie dort erwartet, verwirrt werden und deshalb Fehler ausgeben. Falls dies auftritt, können Sie entweder Ihre Arbeitskopie wieder zurück auf das Haupt-Projektarchiv schalten und warten bis das Spiegel-Projektarchiv aktuell ist oder Ihre Arbeitskopie auf eine Revision zurücksetzen, von der Sie wissen, dass sie im synchronisierten Projektarchiv vorhanden ist, und dann noch einmal das Umschalten versuchen.

Zum Schluss sollte Ihnen bewusst sein, dass die von svnsync angebotene revisionsbasierte Replikation genau das ist – die Replikation von Revisionen. Nur die durch das Format der Subversion-Auszugsdateien übertragene Information ist replizierbar. Somit besitzen Werkzeuge wie svnsync (und svnrdump, das wir in „Projektarchiv-Daten-Migration mit svnrdump“ erörtern) dieselben Einschränkungen wie der Auszugsstrom und beinhalten weder Dinge wie Hook-Implementierungen, Projektarchiv- oder Server-Konfigurationen, unvollständige Transaktionen noch Anwendersperren auf Pfaden im Projektarchiv.

Sicherung des Projektarchivs

Trotz zahlreicher technischer Fortschritte seit der Geburt des modernen Computers bleibt eine Sache unglücklicherweise wahr: manchmal geht etwas richtig schief. Eine kleine Auswahl von schlimmen Dingen, die das Schicksal auch auf den gewissenhaftesten Administrator loslassen kann, sind Stromausfälle, Netzzusammenbrüche, defekter Speicher und Festplattenabstürze. So kommen wir zu einem sehr wichtigen Thema: Wie mache ich Sicherheitskopien von den Daten meines Projektarchivs?

Dem Administrator stehen zwei Arten von Sicherungsmethoden zur Verfügung: vollständig und inkrementell. Eine vollständige Sicherungskopie des Projektarchivs beinhaltet eine umfassende Speicherung aller Informationen, die für die Wiederherstellung des Projektarchivs im Katastrophenfall benötigt werden. Dies bedeutet gewöhnlich eine Kopie des gesamten Projektarchiv-Verzeichnisses (inklusive der Berkeley-DB- oder FSFS-Umgebung). Inkrementelle Sicherungen haben einen geringeren Umfang: nur die Teile des Projektarchivs, die sich seit der letzten Sicherung geändert haben.

Was eine vollständige Sicherung betrifft, scheint der naive Ansatz vernünftig zu sein; jedoch besteht beim einfachen rekursiven Kopieren des Verzeichnisses das Risiko, eine fehlerhafte Sicherung zu erstellen, sofern nicht alle anderen Zugriffe auf das Projektarchiv verhindert werden. Für Berkeley DB beschreibt die Dokumentation eine bestimmte Reihenfolge, in der die Datenbankdateien kopiert werden können, um eine gültige Sicherungskopie zu gewährleisten. Eine ähnliche Reihenfolge gibt es für FSFS-Daten. Allerdings brauchen Sie diese Algorithmen nicht selbst zu implementieren, da das Subversion-Entwicklerteam das bereits getan hat. Der Befehl svnadmin hotcopy kümmert sich um die Details, die für eine Sicherungskopie während des Betriebes erforderlich sind. Der Aufruf ist so trivial wie die Bedienung von Unix' cp oder Windows' copy:

$ svnadmin hotcopy /var/svn/repos /var/svn/repos-backup

Das Ergebnis der Sicherung ist ein vollständig funktionsfähiges Subversion-Projektarchiv, das jederzeit die Aufgaben Ihres Projektarchivs übernehmen kann, falls irgendetwas Schlimmes passieren sollte.

Ein zusätzliches Werkzeug für diesen Befehl steht auch zur Verfügung. Im Verzeichnis tools/backup/ des Subversion-Quelltextpaketes liegt das Skript hot-backup.py. Dieses Skript ergänzt svnadmin hotcopy um ein wenig Sicherungsverwaltung, indem es Ihnen erlaubt, lediglich eine konfigurierbare Anzahl der letzten Sicherungskopien jedes Projektarchivs zu behalten. Es verwaltet automatisch die Namen der gesicherten Projektarchiv-Verzeichnisse, um Kollisionen mit vorherigen Sicherungen zu vermeiden und löscht ältere Sicherungen, so dass nur die jüngsten übrig bleiben. Selbst wenn Sie ebenfalls eine inkrementelle Sicherung haben, sollten Sie dieses Programm regelmäßig aufrufen. Sie könnten beispielsweise hot-backup.py mit einem Programmstarter (so wie cron auf Unix Systemen) verwenden, der es jede Nacht (oder in einem Zeitintervall, das Ihnen sicher erscheint) aufruft.

Einige Administratoren verwenden einen unterschiedlichen Sicherungsmechanismus, der auf der Erzeugung und Speicherung von Projektarchiv-Auszugs-Daten basiert. In „Projektarchiv-Daten woanders hin verschieben“ haben wir beschrieben, wie svnadmin dump mit der Option --incremental verwendet werden kann, um eine inkrementelle Sicherung einer Revision oder eines Bereichs von Revisionen zu erstellen. Natürlich können Sie davon eine vollständige Sicherung bekommen, wenn Sie die Option --incremental weglassen. Der Vorteil dieser Methode besteht darin, dass das Format der gesicherten Information flexibel ist – es erfordert keine bestimmte Plattform, keinen bestimmten Typ eines versionierten Dateisystems, keine bestimmte Version von Subversion oder der von ihm verwendeten Bibliotheken. Diese Flexibilität kommt allerdings zu dem Preis, dass die Wiederherstellung der Daten sehr lange dauern kann – länger mit jeder neuen Revision, die ins Projektarchiv übertragen wird. Wie bei vielen verschiedenen Sicherungsmethoden werden auch hier Änderungen an Revisions-Eigenschaften bereits gesicherter Revisionen nicht berücksichtigt, sofern es sich um eine nicht-überlappende inkrementelle Sicherung handelt. Wir raten aus diesen Gründen davon ab, sich ausschließlich auf Sicherungsstrategien zu verlassen, die alleine auf Auszügen basieren.

Beginnend mit Subversion 1.8 akzeptiert svnadmin hotcopy die Option --incremental und unterstützt den inkrementellen Hotcopy-Modus für FSFS-Projektarchive. Bei dem inkrementellen Hotcopy-Modus werden bereits kopierte Revisionsdaten nicht erneut kopiert. Wenn die Option --incremental mit svnadmin hotcopy verwendet wird, kopiert Subversion nur neue Revisionen sowie Revisionen, die seit der letzten Hotcopy-Operation eine geänderte Größe oder einen geänderten Änderungszeitstempel haben. Darüber hinaus wird die Leistungsfähigkeit von svnadmin hotcopy --incremental nur durch Plattenzugriffe eingeschränkt, anders als bei svnsync oder svnadmin dump --incremental. Aus diesem Grund kann ein inkrementelles Hotcopy eine riesige Zeitersparnis bei der Sicherung eines großen Projektarchivs sein.

Wie Sie sehen können, hat jeder der verschiedenen Sicherungstypen seine Vor- und Nachteile. Bei weitem am einfachsten ist die vollständige Sicherungskopie im laufenden Betrieb, die stets ein perfektes, einsatzfähiges Abbild Ihres Projektarchivs erzeugt. Falls Ihrem Projektarchiv irgendetwas Schlimmes widerfahren sollte, können Sie es durch eine einfache rekursive Verzeichniskopie aus der Sicherung wiederherstellen. Falls Sie mehrere Sicherungen Ihres Projektarchivs vorhalten, benötigt leider jede dieser vollständigen Kopien genauso viel Plattenplatz wie das Original. Im Gegensatz dazu lassen sich inkrementelle Sicherungen schneller erzeugen und platzsparender sichern. Allerdings kann die Wiederherstellung eine Plage sein, da oft mehrere inkrementelle Sicherungen eingespielt werden müssen. Andere Methoden wiederum haben auch ihre Besonderheiten. Administratoren müssen das Gleichgewicht zwischen den Kosten der Sicherung und den Kosten der Wiederherstellung finden.

Das Programm svnsync (siehe „Projektarchiv Replikation“) bietet tatsächlich einen handlichen Ansatz dazwischen. Falls Sie regelmäßig einen nur lesbaren Spiegel mit Ihrem Haupt-Projektarchiv synchronisieren, stellt der Spiegel einen ausgezeichneten Kandidaten dar, um für Ihr Haupt-Projektarchiv einzuspringen, falls es mal umkippt. Der Hauptnachteil dieses Ansatzes besteht darin, dass nur versionierte Projektarchiv-Daten synchronisiert werden – Projektarchiv-Konfigurationsdateien, benutzerdefinierte Sperren auf Projektarchiv-Pfaden und andere Dinge, die sich zwar im physikalischen Projektarchiv-Verzeichnis befinden können, jedoch nicht innerhalb des virtuellen versionierten Dateisystems des Projektarchivs, werden durch svnsync nicht berücksichtigt.

In jedem Sicherungs-Szenario müssen sich Projektarchiv-Administratoren bewusst sein, inwiefern Änderungen an unversionierten Revisions-Eigenschaften Auswirkungen auf die Sicherungen haben. Da diese Änderungen allein keine Revisionen erzeugen, werden auch keine post-commit-Hooks ausgelöst; es kann sogar sein, dass die Hooks pre-revprop-change und post-revprop-change nicht ausgelöst werden. [60] Und da Sie Revisions-Eigenschaften ohne Rücksicht auf die zeitliche Abfolge ändern können – Sie können jederzeit die Eigenschaften jeder Revision ändern – könnte eine inkrementelle Sicherung der letzten paar Revisionen eine Änderung an einer Revision aus einer vorangegangenen Sicherung übersehen.

Im Allgemeinen braucht nur ein echter Paranoiker nach jeder Übergabe eine vollständige Sicherung des Projektarchivs. Eine vollständige Sicherheitskopie des Projektarchivs im laufenden Betrieb im Rahmen einer systemweiten, nächtlichen Sicherung sollte ein Projektarchiv-Administrator jedoch erwägen, unter der Voraussetzung, dass das Projektarchiv bereits irgendeinen Redundanzmechanismus mit der nötigen Granularität verwendet (etwa Übergabe-E-Mails oder inkrementelle Auszüge). Es sind Ihre Daten – schützen Sie sie, wie es Ihnen passt.

Oftmals ist der beste Ansatz für die Projektarchiv-Sicherung ein diversifizierter, der die Stärken von Kombinationen der hier beschriebenen Methoden ausspielt. Die Subversion-Entwickler beispielsweise sichern jede Nacht das Subversion-Quelltext-Projektarchiv mit hot-backup.py und einem rsync dieser vollständigen Sicherungen von einem entfernten Standort aus; sie halten mehrere Archive aller Übergabe- und Eigenschafts-Änderungs-E-Mails vor und sie haben Spiegel des Projektarchivs, die von Freiwilligen mit svnsync verwaltet werden. Ihre Lösung könnte ähnlich aussehen, sollte aber Ihren Bedürfnissen entsprechen und das empfindliche Gleichgewicht zwischen Bequemlichkeit und Paranoia aufrechterhalten. Egal, was Sie machen: überprüfen Sie Ihre Sicherungen ab und an – was nutzt ein Reservereifen mit einem Loch? Obwohl all das Ihr Material nicht vor der eisernen Faust des Schicksals zu retten vermag, sollte es Ihnen sicherlich helfen, sich aus diesen schwierigen Zeiten zu erholen.

Verwaltung von Projektarchiv UUIDs

Subversion-Projektarchive haben eine mit ihnen verknüpfte, universelle, eindeutige Identifizierung (universally unique identifier, UUID). Dieser UUID wird von Subversion-Clients verwendet, um die Identität eines Projektarchivs zu verifizieren, falls andere Methoden nicht ausreichend sind (wie die Überprüfung des Projektarchiv-URLs, der sich im Lauf der Zeit ändern kann). Selten, wenn überhaupt, müssen sich Subversion-Projektarchiv-Administratoren weitergehende Gedanken über Projektarchiv UUIDs machen, anstatt sie als triviales Implementierungsdetail von Subversion zu betrachten. Manchmal jedoch gibt es einen Grund, der Aufmerksamkeit für dieses Detail verlangt.

Im Allgemeinen möchten Sie, dass die UUIDs Ihrer aktiven Projektarchive eindeutig sind. Das ist schließlich der Sinn von UUIDs. Jedoch gibt es Gelegenheiten, bei denen Sie möchten, dass die UUIDs zweier Projektarchive identisch sind. Wenn Sie beispielsweise zu Sicherungszwecken eine Kopie eines Projektarchivs machen, möchten Sie, dass die Sicherungskopie ein perfektes Abbild des Originals ist, so dass die Anwender nach einer Wiederherstellung des Projektarchivs aus der Sicherheitskopie nicht das Gefühl haben, es mit einem unterschiedlichen Projektarchiv zu tun zu haben. Beim Erstellen bzw. beim Laden eines Auszugs der Projektarchiv-Historie (wie oben in „Projektarchiv-Daten woanders hin verschieben“ beschrieben) können Sie entscheiden, ob der im Auszugsstrom befindliche UUID auf das Projektarchiv angewendet werden soll, in das Sie die Daten laden. Die besonderen Umstände diktieren hier das richtige Verhalten.

Eine Projektarchiv-UUID kann auf verschiedene Art und Weise gesetzt (oder zurückgesetzt) werden, falls sie es müssen. Seit Subversion 1.5 wird einfach der Befehl svnadmin setuuid verwendet. Wenn Sie diesem Befehl einen ausdrücklichen UUID mitgeben, wird die Wohlgeformtheit des UUID überprüft und der UUID des Projektarchivs auf diesen Wert gesetzt. Wenn Sie den UUID weglassen, wird ein nagelneuer UUID für Ihr Projektarchiv erzeugt.

$ svnlook uuid /var/svn/repos
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec 
$ svnadmin setuuid /var/svn/repos   # neuen UUID erzeugen
$ svnlook uuid /var/svn/repos
3c3c38fe-acc0-11dc-acbc-1b37ff1c8e7c
$ svnadmin setuuid /var/svn/repos \ 
           cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec  # alten UUID wiederherstellen
$ svnlook uuid /var/svn/repos
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$

Für Anwender älterer Versionen als Subversion 1.5 sieht die Sache etwas komplizierter aus. Sie können den UUID eines Projektarchivs ausdrücklich setzen, indem Sie einen Projektarchiv-Auszugs-Fragment mit dem neuen UUID durch den Befehl svnadmin load --force-uuid REPOS-PATH leiten.

$ svnadmin load --force-uuid /var/svn/repos <<EOF
SVN-fs-dump-format-version: 2

UUID: cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
EOF
$ svnlook uuid /var/svn/repos
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$

Die Erzeugung eines nagelneuen UUID mit älteren Versionen von Subversion gestaltet sich jedoch nicht so einfach. Am besten finden Sie eine andere Möglichkeit zum Erzeugen des UUIDs und setzen anschließend den Projektarchiv-UUID auf diesen Wert.



[55] Das ist doch überhaupt der Grund dafür, Versionskontrolle einzusetzen, oder?

[56] Das bewusste, vorsichtige Entfernen bestimmter Teile versionierter Daten wird tatsächlich von wirklichen Anwendungsfällen verlangt. Das ist der Grund, warum eine Vernichtungs-Funktion eine der am häufigsten gewünschten Funktionen von Subversion ist, von der die Subversion-Entwickler hoffen, sie bald zur Verfügung stellen zu können.

[57] Obwohl svnadmin dump ein konsistentes Vorgehen bezüglich führender Schrägstriche vorweisen kann (indem es sie nicht einfügt), sind andere Programme, die Auszugsdateien erzeugen eventuell nicht so konsistent.

[58] Tatsächlich kann es gar nicht nur lesbar sein, denn sonst hätte svnsync ein echtes Problem, die Versionshistorie hineinzukopieren.

[59] Seien Sie jedoch vorgewarnt, dass, obwohl der durchschnittliche Leser nur ein paar Sekunden benötigt, um diesen Absatz und die ihm folgende Beispielausgabe zu erfassen, die tatsächlich für eine vollständige Spiegelung erforderliche Zeit um Einiges länger ist.

[60] svnadmin setlog kann auf eine Art aufgerufen werden, dass die Hook-Schnittstelle völlig umgangen wird.