Kürzlich erhielt ich den Auftrag, einige Subversion-Repositorys auf einen neuen Server umzuziehen. Dazu sollte noch ein Trac (Bug-/Issuetracker) auf den Rechner sowie WebDAV angepasst werden. Alles in allem keine große Sache. Es sollte innerhalb eines Arbeitstages gegessen sein. Sollte ...
Nach einigen Vorbereitungsarbeiten warf ich im ersten Repository ein beherztes svnadmin dump $REPO > $REPODUMP an und wartete. Kurz vor Ende brach der Prozess ab und meldete svnadmin: Found malformed header in revision file. Eine Websuche ergab, dass die Datenbank wahrscheinlich korrupt ist. Die Fehlerquelle liegt wahrscheinlich im Zusammenspiel von mod_dav und Subversion. Gleiches kann auch mit svnserve auftreten. Soweit ich las, ist der Fehler nicht genau reproduzierbar. Daher existieren auch keine Fixe. Eine zweite mögliche Fehlerquelle liegt in der Hardware. Auf dem Server gab es wohl in dem Zeitraum Probleme mit dem RAID. Eventuell kommt das Problem auch daher. Die Mailingliste von Subversion ergab hier nur einen Hinweis auf das Pythonskript fsfsverify von John Szakmeister. Im Verzeichnis $REPO/db/revs liegen die bisherigen Revisionen und man übergibt dem Skript einfach die fehlerhafte Datei. (Wobei das nur für das Format FSFS gilt.) Aber das einzige, was das Skript dabei ausspuckte, war:
File “/foo/bar/fsfsverify/fsfsverify.py”, line 661, in __init__
(field, value) = line.split(’:’, 1)
Was tun?, sprach Zeus. Ich entschied mich, einen genaueren Blick in die Struktur von FSFS zu werfen und auch den Autor des Programms um Rat zu fragen. FSFS hat den Vorteil, dass es pro Datei immer nur einen binären Diff mit Metainformationen speichert. Somit könnte man praktisch die Informationen wieder zurückgewinnen, denn das Format des Diffs ist ebenfalls offengelegt. Jedoch ist bei dem Repository ein durchschnittlicher Diff 1,5MB (sic!) groß. Da will man nichts händisch zusammenbasteln. John antwortete mir glücklicherweise und bot seine Hilfe an. Nach einigem Mailaustausch schafften wir es, die Datenbank zu reparieren. Der dabei entstandene Diff entspricht zwar nicht dem Originaldiff. Aber er kommt nahe dran.
So kann ich jetzt mit einer Woche Verzögerung das Projekt beenden. Trotz der Verzögerung sind alle glücklich.