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.
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. Anschließend werden wir kurz einige der zum Berkeley-DB-Paket gehörenden Dienstprogramme untersuchen, die auf die Besonderheiten der von Subversion verwendeten Datenbank zugeschnittene Funktionen anbieten, die mit Subversions eigenen Werkzeugen nicht verfügbar sind.
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 Kommandozeilenprogrammen 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“ können Sie in einer vollständigen Aufstellung der Unterbefehle nachlesen, was jeder zu bieten hat.
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 übergeben 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 | |
---|---|
Beachten Sie, dass Sie nur Transaktionen untersuchen
können, die noch nicht übergeben sind. Die meisten
Projektarchive haben keine derartigen Transaktionen, da
Transaktionen entweder übergeben (in diesem Fall sollten
Sie darauf mit der Option |
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 (Mon, 04 Nov 2002) 43 Den üblichen griechischen Baum hinzugefügt. $
Die Ausgabe von svnlook info besteht aus dem Folgenden in entsprechender Reihenfolge:
Der Autor gefolgt von einem Zeilenvorschub
Das Datum gefolgt von einem Zeilenvorschub
Die Anzahl der Zeichen der Protokollnachricht gefolgt von einem Zeilenvorschub.
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 Scripten und anderen Programmen, die um diesen Befehl herumgeschrieben wurden, intelligente Entscheidungen in Bezug auf die Protokollnachricht zu treffen, etwa wieviel Speicher für die Nachricht anzufordern ist oder zumindest wieviele 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“ für eine vollständige Referenz der Funktionen von svnlook.
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.
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 help (?, h) $
Später in diesem Kapitel werden wir mehr über das Replizieren von Projektarchiven mit svnsync reden (siehe „Projektarchiv Replikation“).
Obwohl es kein offizielles Glied in der Werkzeugkette
von Subversion ist, handelt es sich bei dem Script
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 enthalten Dateien,
die die Änderungen in einer einzelnen Revision beschreiben
sowie Dateien, die die zu einer Revision gehörenden Eigenschaften
beinhalten. Projektarchive, die in einer früheren Version als
Subversion 1.5 erzeugt wurden, legen diese Dateien in zwei
Verzeichnissen ab – eins pro Dateityp. Während neue
Revisionen an das Projektarchiv übergeben werden, legt
Subversion dort immer mehr Dateien ab – im Lauf der
Zeit kann die Anzahl der Dateien recht groß werden. Es wurde
festgestellt, dass dies bei bestimmten netzbasierten
Dateisystemen zu Leistungseinbußen kommen kann.
Subversion 1.5 legt FSFS-basierte Projektarchive mit einer geringfügig veränderten Struktur an, in der der Inhalt dieser beiden Verzeichnisse aufgebrochen ist, d.h. über mehrere Unterverzeichnisse aufgeteilt ist. Das kann die Zeit erheblich beschleunigen, die benötigt wird, um eine dieser Dateien zu finden und führt somit zu einer allgemeinen Leistungssteigerung beim Lesen aus dem Projektarchiv. Die Anzahl der Unterverzeichnisse für diese Dateien ist jedoch konfigurierbar, und hier setzt fsfs-reshard.py an. Dieses Script mischt die Dateistruktur des Projektarchivs und ordnet sie gemäß der Anzahl der gewünschten Unterverzeichnisse neu an. Das ist inbesonders dann nützlich, wenn ein älteres Projektarchiv in die neue Struktur von Subversion 1.5 überführt werden soll (was Subversion nicht automatisch für Sie macht) oder falls ein bereits aufgeteiltes Projektarchiv noch feiner eingestellt werden soll.
Falls Sie ein Projektarchiv verwenden, das auf Berkeley DB
basiert, befindet sich die gesamte Struktur und die Daten
Ihres versionierten Dateisystems in einer Menge von
Datenbanktabellen innerhalb des Unterverzeichnisses
db/
Ihres Projektarchivs. Dieses
Unterverzeichnis ist ein gewöhnliches Verzeichnis einer
Berkeley-DB-Umgebung und kann deshalb mit irgendeinem der
Berkeley Datenbankwerkzeuge verwendet werden, die
normalerweise mit Berkeley DB ausgeliefert werden.
Für die tägliche Arbeit mit Subversion werden diese Werkzeuge nicht benötigt. Die meisten Funktionen, die üblicherweise für Subversion-Projektarchive gebraucht werden, sind in svnadmin integriert worden. Beispielsweise liefern svnadmin list-unused-dblogs und svnadmin list-dblogs eine Teilmenge dessen, was vom Berkeley-Dienstprogramm db_archive angeboten wird, und svnadmin recover spiegelt die verbreiteten Anwendungsfälle von db_recover wieder.
Trotzdem gibt es noch ein paar Berkeley-DB-Werkzeuge, die Ihnen nützlich sein könnten. Die Programme db_dump und db_load schreiben bzw. lesen ein spezielles Dateiformat, das die Schlüssel und Werte in einer Berkeley-DB-Datenbank beschreibt. Da Berkeley-Datenbanken nicht zwischen Rechnerarchitekturen portierbar sind, stellt dieses Format ein nützliches Verfahren zur Übertragung der Datenbanken zwischen Maschinen zur Verfügung, wobei die Architektur oder das Betriebssystem keine Rolle spielen. Später in diesem Kapitel werden wir noch beschreiben, wie Sie auch svnadmin dump und svnadmin load für ähnliche Zwecke verwenden können, doch db_dump und db_load können bestimmte Aufgaben genausogut und viel schneller erledigen. Sie können auch dabei dienlich sein, wenn der erfahrene Berkeley-DB-Hacker aus irgendwelchen Gründen die Daten in einem BDB-basierten Projektarchiv direkt vor Ort anpassen muss, was die Dienstprogramme von Subversion nicht erlauben. Ferner liefert das Dienstprogramm db_stat nützliche Informationen über den Zustand Ihrer Berkeley-DB-Umgebung, wozu ausführliche Statistiken über das Sperr- und Speicher-Teilsystem gehören.
Besuchen Sie für weitergehende Informationen zur Berkeley-Werkzeugsammlung den Dokumentationsabschnitt der Berkeley-DB-Abteilung auf der Seite von Oracle bei http://www.oracle.com/technology/documentation/berkeley-db/db/.
Manchmal kommt es vor, dass ein Benutzer 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 Benutzer den Protokolleintrag aus
der Ferne mit dem Befehl svn propset (siehe
svn propset)
„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-
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 | |
---|---|
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. |
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.
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. Und für Projektarchive, die mit Subversion 1.4 oder später angelegt wurden, ist die Platzersparnis sogar noch besser – jetzt sind die Volltexte der Dateiinhalte selbst komprimiert.
Anmerkung | |
---|---|
Da alle delta-kodierten Daten in einem BDB-basierten Projektarchiv in einer einzigen Berkeley-DB-Datenbankdatei gespeichert werden, wird die verringerte Größe der gespeicherten Werte nicht unmittelbar die Größe der Datenbankdatei verringern. Berkeley DB führt jedoch intern Buch über unbenutzte Bereiche der Datenbankdatei und wird zunächst jene aufbrauchen, bevor die Datenbankdatei selbst vergrößert wird. Während Delta-Kodierung also nicht unmittelbare Platzersparnis bringt, kann sie jedoch das künftige Wachstum der Datenbank drastisch verlangsamen. |
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 Benutzer 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.1, „txn-info.sh (ausstehende Transaktionen anzeigen)“ enthält ein kleines Shell-Script, das schnell eine Übersicht über jede ausstehende Transaktion in Ihrem Projektarchiv erzeugen kann.
Beispiel 5.1. 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 Scriptes 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 (Tue, 04 Sep 2001) 0 ---[ Transaktion 3a1 ]------------------------------------------- harry 2001-09-10 16:50:30 -0500 (Mon, 10 Sep 2001) 39 Versuch, über eine schlechte Netzverbindung abzuliefern. ---[ Transaktion a45 ]------------------------------------------- sally 2001-09-12 11:09:28 -0500 (Wed, 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 Zugriffsprotokolldateien 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 Zombiezustand befindet.
Bis vor kurzer Zeit waren die größten Plattenplatzfresser bei BDB-basierten Subversion-Projektarchive die Protokolldateien, in die Berkeley DB zunächst alle Schritte hineinschreibt, bevor es die eigentlichen Datenbankdateien verändert. Diese Dateien halten alle Aktionen der Datenbank auf dem Weg von einem Zustand zum nächsten fest – während die Datenbankdateien zu jeder Zeit einen bestimmten Zustand widerspiegeln, beinhalten die Protokolldateien all die vielen Änderungen auf dem Weg zwischen den Zuständen. Somit können sie sehr schnell wachsen und sich anhäufen.
Glücklicherweise hat die Datenbankumgebung beginnend mit
der Version 4.2 der Berkeley DB die Fähigkeit, ihre eigenen
unbenutzten Protokolldateien automatisch zu entfernen. Alle
Projektarchive, die mit einem svnadmin
angelegt wurden, das mit Berkeley DB Version 4.2 oder später
übersetzt wurde, werden mit automatischer
Protokolldateientfernung konfiguriert. Wenn Sie diese
Funktion nicht möchten, geben Sie dem Befehl
svnadmin create einfach die Option
--bdb-log-keep
mit. Sollten Sie das
vergessen oder es sich später anders überlegen, editieren
Sie einfach die Datei DB_CONFIG
im
Verzeichnis db
Ihres Projektarchivs indem
Sie die Zeile mit der Direktive set_flags
DB_LOG_AUTOREMOVE
auskommentieren und starten dann
svnadmin recover auf Ihrem Projektarchiv, um
die Konfigurationsänderung zu aktivieren. Siehe „Konfiguration von Berkeley DB“ für weitere
Informationen zur Datenbankkonfiguration.
Ohne eine Art automatische Protokolldateientfernung aktiviert zu haben, häufen sich die Protokolldateien während der Nutzung des Projektarchivs an. Es ist eigentlich ein Merkmal des Datenbanksystems – Sie sollten ausschließlich mit Hilfe der Protokolldateien in der Lage sein, Ihre gesamte Datenbank zu rekonstruieren, so dass diese Protokolldateien sehr nützlich für eine Wiederherstellung im Katastrophenfall sein können. Jedoch möchten Sie normalerweise die nicht mehr von Berkeley DB verwendeten Protokolldateien archivieren und sie zur Platzersparnis von der Platte entfernen. Verwenden Sie den Befehl svnadmin list-unused-dblogs, um die unbenutzten Protokolldateien anzuzeigen:
$ svnadmin list-unused-dblogs /var/svn/repos /var/svn/repos/log.0000000031 /var/svn/repos/log.0000000032 /var/svn/repos/log.0000000033 … $ rm `svnadmin list-unused-dblogs /var/svn/repos` ## Plattenplatz zurückgewonnen!
Warnung | |
---|---|
BDB-basierte Projektarchive, deren Protokolldateien ein Bestandteil eines Sicherungs- oder Notfallplans sind, sollten nicht die automatische Entfernung verwenden. Die Wiederherstellung der Daten eines Projektarchivs kann nur gewährleistet werden, wenn alle Protokolldateien verfügbar sind. Falls einige der Protokolldateien von der Platte entfernt werden, bevor das Sicherungssystem die Gelegenheit bekommt, sie woandershin zu kopieren, ist die unvollständige Menge gesicherter Protokolldateien tatsächlich nutzlos. |
Wie in „Berkeley DB“ erwähnt wurde, kann ein Berkeley-DB-Projektarchiv manchmal einfrieren, falls es nicht ordnungsgemäß geschlossen wird. Wenn das passiert, muss ein Administrator die Datenbank in einen konsistenten Zustand zurückfahren. Das gilt aber nur für BDB-basierte Projektarchive – falls Sie FSFS-basierte verwenden, sind Sie davon nicht betroffen. Und falls Sie Subversion 1.4 mit Berkeley DB 4.4 oder später verwenden, werden Sie feststellen, dass Subversion für diese Situationen wesentlich unempfindlicher geworden ist. Trotzdem kommt es vor, dass sich Berkeley-DB-Projektarchive verklemmen, und Administratoren müssen wissen, wie sie sicher damit umgehen.
Um die Daten in Ihrem Projektarchiv zu schützen, verwendet Berkeley DB einen Sperrmechanismus. Dieser Mechanismus stellt sicher, dass Teile der Datenbank nicht gleichzeitig durch mehrere Zugriffe verändert werden und jeder Prozess die Daten beim Lesen aus der Datenbank im korrekten Zustand sieht. Wenn ein Prozess irgendetwas in der Datenbank ändern muss, prüft er zunächst, ob eine Sperre auf den Zieldaten liegt. Sind die Daten nicht gesperrt, sperrt der Prozess die Daten, nimmt die Änderungen vor und entsperrt die Daten wieder. Andere Prozesse müssen auf die Freigabe der Sperre warten, bevor sie wieder auf diesen Datenbankabschnitt zugreifen dürfen. (Das hat nichts mit den Sperren zu tun, die Sie als Benutzer auf versionierte Dateien im Projektarchiv vergeben können; wir versuchen die Verwirrung, die durch diese Terminologie verursacht wird, in Die drei Bedeutungen von „Sperre“ zu klären.)
Während der Nutzung Ihres Projektarchivs können fatale Fehler oder Unterbrechungen einen Prozess daran hindern, die von ihm in der Datenbank gesetzten Sperren wieder zu entfernen. Als Ergebnis ist das Datenbanksystem „verklemmt“. Wenn das passiert, laufen alle Versuche ins Leere, auf die Datenbank zuzugreifen (da jeder neue Prozess darauf wartet, dass die Sperre entfernt wird – was aber nicht passieren wird).
Keine Panik, falls das Ihrem Projektarchiv widerfahren sollte! Das Berkeley-DB-Dateisystem nutzt die Vorteile von Datenbanktransaktionen, Sicherungspunkten sowie vorausschreibender Journalierung, um zu gewährleisten, dass nur die katastrophalsten Ereignisse [32] dauerhaft die Datenbankumgebung zerstören können. Ein ausreichend paranoider Projektarchiv-Administrator wird irgendwie Sicherungen der Daten des Projektarchivs an einem anderen Ort verwahren, doch rennen Sie noch nicht zum Schrank mit den Sicherungsbändern.
Verwenden Sie stattdessen das folgende Rezept, um Ihr Projektarchiv zu „entklemmen“:
Stellen Sie sicher, dass keine Prozesse auf das Projektarchiv zugreifen (oder einen Zugriffsversuch machen). Für netzbasierte Projektarchive bedeutet das, auch den Apache-HTTP-Server oder den svnserve-Dämon zu stoppen.
Melden Sie sich als der Benutzer an, dem das Projektarchiv gehört und der es verwaltet. Das ist wichtig, da eine Wiederherstellung unter einer falschen Benutzerkennung dazu führen kann, dass die Berechtigungen auf den Dateien eines Projektarchivs derart verändert werden können, dass der Zugriff auf das Projektarchiv auch dann nicht mehr möglich wird, wenn es „entklemmt“ ist.
Starten Sie den Befehl svnadmin recover
/var/svn/repos
. Sie sollten eine Ausgabe
ähnlich dieser sehen:
Exklusiven Zugriff auf das Projektarchiv erlangt Bitte warten, die Wiederherstellung des Projektarchivs kann einige Zeit dauern ... Wiederherstellung vollständig abgeschlossen. Die neueste Revision des Projektarchivs ist 19.
Die Ausführung dieses Befehls kann viele Minuten dauern.
Machen Sie einen Neustart des Server-Prozesses.
Dieses Vorgehen behebt fast jeden Fall von
Projektarchiv-Verklemmung. Stellen Sie sicher, dass Sie diesen
Befehl als der Benutzer ausführen, der Eigentümer und
Verwalter der Datenbank ist, nicht einfach als
root
. Ein Teil des
Wiederherstellungsprozesses könnte diverse Datenbankdateien
völlig neu erzeugen (z.B. gemeinsame Speicherbereiche). Wenn
Sie die Wiederherstellung als root
ausführen, werden diese Dateien dem Benutzer
root
zugeordnet, was bedeutet, dass selbst
nach der Wiederherstellung der Verbindung zur Außenwelt
gewöhnliche Benutzer keinen Zugriff mehr bekommen
werden.
Falls das oben beschriebene Vorgehen aus irgendwelchen
Gründen die Verklemmung Ihres Projektarchivs nicht beseitigt,
sollten Sie zwei Dinge tun. Schieben Sie zunächst ihr
beschädigtes Projektarchiv an die Seite (indem Sie es etwa in
repos.BROKEN
umbenennen) und spielen
seine jüngste Sicherung ein. Schicken Sie dann eine E-Mail an
die Subversion-Mailing-Liste
(<users@subversion.tigris.org>
), in der Sie Ihr
Problem detailliert beschreiben. Die Integrität der Daten
genießt bei den Entwicklern von Subversion allerhöchste
Priorität.
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.
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 Benutzer 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 Benutzer 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 | |
---|---|
Das Auszugsformat eines Subversion Projektarchivs beschreibt nur versionierte Änderungen. Es beinhaltet keine Informationen über unvollendete Transaktionen, von Benutzern gesetzte Sperren auf Pfade im Projektarchiv, Anpassungen an Projektarchiv- oder Server-Konfigurationen (inklusive Hook-Scripten) usw. |
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-Scripte 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 Script, 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 … $
Zum Schluss erwähnen wir noch einen Anwendungsfall für das Auszugsformat – die Umwandlung aus einem unterschiedlichen Speicherverfahren oder gar aus einem unterschiedlichen Versionskontrollsystem. Da das Format der Auszugsdatei größtenteils menschenlesbar ist, sollte es einfach sein, gewöhnliche Änderungsmengen – von denen jede als Revision behandelt werden sollte – mit diesem Format zu beschreiben. Tatsächlich verwendet das Dienstprogramm cvs2svn (siehe „Ein Projektarchiv von CVS nach Subversion überführen“) dieses Auszugsformat, um den Inhalt eines CVS-Projektarchivs darzustellen, so dass er in ein Subversion-Projektarchiv kopiert werden kann.
Da Subversion Ihre versionierte Historie mindestens mit binären Differenzalgorithmen und Datenkompression abspeichert (optional in einem völlig undurchsichtigen Datenbanksystem), ist der Versuch manueller Eingiffe 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. [33] 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). [34] 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 woandershin 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, um den Auszug anzulegen und svnadmin 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 jedesmal 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 | |
---|---|
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.
|
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 Benutzer die Kontrolle darüber zu geben, wie hiermit verfahren werden soll, bietet svndumpfilter die folgenden Kommandozeilenoptionen:
--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, [35] 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.
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.
Seit Version 1.4 stellt Subversion ein Programm zur Handhabung solcher Szenarien zur Verfügung – svnsync. Im Wesentlichen funktioniert das, 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 | |
---|---|
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. |
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 eins der verfügbaren Speicherverfahren benutzen (siehe „Auswahl der Datenspeicherung“), doch es darf noch keine Versionshistorie enthalten. Das von svnsync verwendete Protokoll zur Übermittlung der Revisionsinformation ist sehr empfindlich gegenüber nicht übereinstimmenden Versionshistorien im Quell- und Ziel-Projektarchiv. Aus dem Grund, dass svnsync nicht verlangen kann, dass das Ziel-Projektarchiv nur lesbar ist, [36] ist die Katastrophe programmiert, wenn erlaubt wird, die Revisions-Historie im Ziel-Projektarchiv mit anderen Mitteln als durch das Spiegeln zu verändern.
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) 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 | |
---|---|
Es ist eine gute Idee, Autorisierungsmaßnahmen zu ergreifen, um Ihrem Projektarchiv-Replikations-Prozess die Arbeit zu ermöglichen, wohingegen anderen Benutzern 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.
Als Dienst an den ausgezeichneten Entwicklern unseres Lieblings-Versionskontrollsystems wollen wir das öffentliche Subversion-Quelltext-Projektarchiv spiegeln 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 Benutzern erlaubt, den Inhalt von Projektarchivs auf diesem Rechner zu lesen, aber zum Ändern dieser Projektarchive eine Authentifizierung der Benutzer 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, Die Administration eines Subversion-Servers behandelt.) Und aus dem alleinigen Grund, es noch interessanter machen zu wollen, werden wir den Replikationsprozess 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
Replikationsprozess 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 Benutzernamen für
unseren Prozess. Nur Übergaben und Änderungen an
Revisions-Eigenschaften unter dem Benutzerkonto
syncuser
werden erlaubt.
Wir verwenden das Hook-System des Projektarchivs sowohl, um
dem Replikationsprozess 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-Script finden Sie
in Beispiel 5.2, „pre-revprop-change-Hook-Script des Spiegel-Projektarchivs“; grundsätzlich stellt es sicher, dass der Benutzer, der die
Eigenschaften ändern möchte, unser syncuser
ist. Falls dies zutrifft, ist die Änderung erlaubt,
anderenfalls wird die Änderung abgelehnt.
Beispiel 5.2. pre-revprop-change-Hook-Script des Spiegel-Projektarchivs
#!/bin/sh USER="$3" if [ "$USER" = "syncuser" ]; then exit 0; fi echo "Ausschließlich der Benutzer syncuser darf Revisions-Eigenschaften ändern" >&2 exit 1
Das deckt Änderungen an Revisions-Eigenschaften ab. Nun müssen
wir sicherstellen, dass nur der Benutzer
syncuser
neue Revisionen an das Projektarchiv
übergeben darf. Wir machen das, indem wir ein
start-commit
-Hook-Script wie das in Beispiel 5.3, „start-commit-Hook-Script des Spiegel-Projektarchivs“
benutzen.
Beispiel 5.3. start-commit-Hook-Script des Spiegel-Projektarchivs
#!/bin/sh USER="$2" if [ "$USER" = "syncuser" ]; then exit 0; fi echo "Ausschließlich der Benutzer syncuser darf neue Revisionen übergeben" >&2 exit 1
Nachdem wir unsere Hook-Scripte 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. In 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 \ http://svn.collab.net/repos/svn \ --sync-username syncuser --sync-password syncpass Eigenschaften für Revision 0 kopiert. $
Unser Ziel-Projektarchiv wird sich nun erinnern, dass es ein Spiegel des öffentlichen Subversion-Quelltext-Projektarchivs ist. Beachten Sie, dass wir einen Benutzernamen und ein Passwort an svnsync übergeben haben – das war für den pre-revprop-change-Hook in unserem Spiegel-Projektarchiv erforderlich.
Anmerkung | |
---|---|
In Subversion 1.4 wurden die an die
Kommandozeilenoptionen Dies ist in Subversion 1.5 mit der Einführung von zwei
neuen Optionspaaren behoben worden. Benutzen Sie
|
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. [37] 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 Überträgt alle laufenden Revisionen von der Quelle, mit der es initialisiert wurde, zum Ziel. … $ svnsync synchronize http://svn.example.com/svn-mirror Übertrage Daten ........................................ Revision 1 übertragen. Eigenschaften für Revision 1 kopiert. Übertrage Daten .. Revision 2 übertragen. Eigenschaften für Revision 2 kopiert. Übertrage Daten ..... Revision 3 übertragen. Eigenschaften für Revision 3 kopiert. … Übertrage Daten .. Revision 23406 übertragen. Eigenschaften für Revision 23406 kopiert. Übertrage Daten . Revision 23407 übertragen. Eigenschaften für Revision 23407 kopiert. Übertrage Daten .... Revision 23408 übertragen. Eigenschaften für Revision 23408 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. Das kommt daher, dass die anfängliche
Übergabe durch den Benutzer syncuser
durchgeführt (und ihm auch zugeschrieben) wird und mit dem
Zeitstempel der Erzeugung dieser Revision versehen wird.
Darüberhinaus erlauben die Subversion zugrundeliegenden
Projektarchiv-Zugriffs-Schnittstellen nicht das beliebige Setzen
von Revisions-Eigenschaften als Teil einer Übergabe. Deshalb folgt
svnsync mit einer unmittelbaren Serie von
Änderungen an den Eigenschaften, die all die Eigenschaften dieser
Revision vom Quell-Projektarchiv ins Ziel-Projektarchiv kopieren.
Das hat auch den Effekt, dass der Autor und der Zeitstempel so
korrigiert werden, dass diese den entsprechenden Werten im
Quell-Projektarchiv entsprechen.
Bemerkenswert 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.
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: svnsync copy-revprops ZIEL_URL [REV[:REV2]] Kopiert die Revisionseigenschaften in einem gegebenen Revisionsbereich von der Quelle, mit der es initialisiert wurde, auf das Ziel. … $ svnsync copy-revprops http://svn.example.com/svn-mirror 12 Eigenschaften für Revision 12 kopiert. $
Das ist Projektarchiv-Replikation in aller Kürze. Sehrwahrscheinlich 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.
Es ist auch möglich, wenn auch nicht sehr verbreitet, dass svnsync Projektarchive spiegelt, in denen der Benutzer unter dessen Kennung es läuft, nur eingeschränkte Rechte besitzt. Es werden dann einfach nur die Teile des Projektarchivs kopiert, die der Benutzer sehen darf. Offensichtlich taugt so ein Spiegel nicht als Sicherheitskopie.
In Subversion 1.5 entwickelte 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.
Was das Zusammenspiel von Benutzern 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 switch mit der Option
--relocate
benutzen, um das Projektarchiv
auszuwählen, mit dem Sie arbeiten wollen; dieser Prozess ist
in svn switch 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 hat svnsync dieselben Einschränkungen wie der Auszugsstrom und beinhaltet nicht Dinge wie Hook-Implementierungen, Projektarchiv- oder Server-Konfigurationen, unvollständige Transaktionen oder Benutzersperren auf Projektarchiv-Pfaden.
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.
Bei der Erstellung von Kopien eines
Berkeley-DB-Projektarchivs können Sie svnadmin
hotcopy sogar mitteilen, nach Abschluss der Kopie
unbenötigte Berkeley-DB-Protokolldateien (siehe „Entfernen unbenutzter Protokolldateien von Berkeley DB“) aus dem
Original-Projektarchiv zu löschen. Geben Sie einfach die Option
--clean-logs
auf der Kommandozeile an.
$ svnadmin hotcopy --clean-logs /var/svn/bdb-repos /var/svn/bdb-repos-backup
Ein zusätzliches Werkzeug für diesen Befehl steht auch zur
Verfügung. Im Verzeichnis tools/backup/
des Subversion-Quelltextpaketes liegt das Script
hot-backup.py. Dieses Script 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 woandershin 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
Berkeley DB. 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
übergeben 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.
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 Sicherungsszenario 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. [38] 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.
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 Benutzer 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 woandershin 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 Benutzer ä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
leiten.REPOS-PATH
$ 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.
[32] Beispielsweise Festplatte + starker Elektromagnet = Desaster.
[33] Das ist doch überhaupt der Grund dafür, Versionskontrolle einzusetzen, oder?
[34] Das bewusste, vorsichtige Entfernen bestimmter Teile versionierter Daten wird tatsächlich von wirklichen Anwendungsfällen verlangt. Das ist der Grund, warum eine „Auslösch“-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.
[35] 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.
[36] Tatsächlich kann es gar nicht nur lesbar sein, denn sonst hätte svnsync ein echtes Problem, die Versionshistorie hineinzukopieren.
[37] 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.
[38] svnadmin setlog kann auf eine Art aufgerufen werden, dass die Hook-Schnittstelle völlig umgangen wird.