TYPO3: Eine intelligentere Sicherung

Auf einer der von mir betreuten Webseiten unter TYPO3 befinden sich seit kurzer Zeit etwa 15.000 (fünfzehntausend) Dokumente in Bildform. TYPO3, als Hochlastsystem konzipiert, hat nunmehr die Eigenschaft, jedes bisschen seiner geleisteten Arbeit zur Wiederverwendung in einem Cache-Speicher abzulegen – eine sehr lobenswerte, aber keinesfalls platzsparende Eigenschaft.

Die einfachste Lösung ist hier ein „tar -czf backup.heute.tgz *“, in diesem Fall werden die gesamten Temporärdateien aber täglich mitgesichert.

Ebenso finden sich temporäre Daten in der Datenbank. Insbesonders mehrsprachige Webseiten mit Nutzern verschiedener Benutzergruppen verbrauchen mehrere hundert Megabyte auf der Festplatte. Es wird jede Seite, für jede Sprache und jedes Benutzerlogin einzeln abgespeichert. Dies ist notwendig, damit ein Benutzer nicht Daten zu sehen bekommt, für die seine Benutzergruppe nicht qualifiziert ist.

Ein Tip: Gehen Sie einfach mal in das Verzeichnis Ihrer TYPO3-Installation und tippen Sie unverbindlich: „du -hsm *“ ein. Suchen Sie die Zeile, welche „typo3temp“ enthält. Die Zahl zu Beginn der Zeile ist die Anzahl der Megabyte, die dieses Verzeichnis belegt. Bei mir steht dort ein Tag nach Löschen des Cache-Speichers bereits 2.239. Zweitausendzweihundertundneununddreissig Megabyte. Und diese Daten können mit einem Klick auf „Clear all cache“ jederzeit zurückgewonnen werden.

Eigentlich ist der Speicherplatzverbrauch kein Problem, da TYPO3 ohnehin für den Betrieb auf einem echten Server ausgelegt ist. Aber bei Backups sehe ich es aus ergonomischen und Performanzgründen einfach nicht ein, riesige Mengen an unnötigen Dateien täglich zu sichern.

Ähnlich sieht es in der Datenbank aus. Alle Tabellen mit „cache_“ im Namen sind eigentlich entbehrlich – die Klick auf „clear all cache“ würde sie eh löschen und sie, im theoretischen Fall einer kompletten Neuinstallation, neu erstellen. Meine cache_pages enthält hier zum Beispiel 1,1 Gigabyte an Daten.

Eigentlich kann auch der sog. „Refindex“ jederzeit neu erstellt werden, allerdings ist dieser Vorgang etwas aufwendiger. Und der Volltextindex (Tabellen mit „index_“ zu Beginn) ist eigentlich auch überflüssig und würde weitere 600 MB pro Backup sparen.

So habe ich nun anstatt des zu Anfangs erwähnten „tar -czf backup.heute.tgz *“ folgendes in Verwendung:

# Prüfen ob das TYPO3 ist
if [ -L "typo3_src" ]; then
  find -type d > ~/DATEILISTE
  find -type l >> ~/DATEILISTE
  find -type f | grep -v ^\.\/typo3temp\/ >> ~/DATEILISTE
  sed -i 's/^\.\///g' ~/DATEILISTE
  tar --no-recursion --files-from="~/DATEILISTE" -cf ~/backups/
fi
rm ~/DATEILISTE

Die erste Zeile (if) prüft auf eine existierende TYPO3 Installation. Die wird am symbolischen Link zum TYPO3-Quellverzeichnis erkannt. Da TYPO3 empfindlich auf fehlende Verzeichnisse und symbolische Links reagiert, fügen wir alle Verzeichnisse und Links der Dateiliste hinzu (erste 2 Zeilen mit „find“).

Der Befehl „find“ beginnt jede Zeile mit „./“ was soviel bedeutet wie „Datei im aktuellen Verzeichnis“. Diese entfernen wir schnell mit „sed“.

In der dritten find-Zeile erstellen wir eine Liste ALLER Dateien im TYPO3-Verzeichnis und streichen alles heraus, das mit „/typo3temp/“ beginnt. Nun teilen wir tar mit, daß wir nur die Dateien der DATEILISTE haben möchten – voila, das Problem mit den temporären Dateien wäre gelöst. Was aber mit der Datenbank?

Hier sichere ich täglich mit dem MySQL-Dienstprogramm „mysqldump“. Ein direktes Kopieren der MySQL-Dateien aus /var/ wäre wesentlich schneller und genauer, allerdings könnte ich dann nicht selber bestimmen was gesichert wird. Und einige Tabellen aller Datenbanken sind in der Datei /var/lib/mysql/ibdata1 verquirlt – ein Rückspielen ginge dann nur durch Ersatz der kompletten Datenbank. Blöd wenn ein Kunde nur versehenlich eine Tabelle gelöscht hat und die wiederhergestellt haben möchte.

Aber auch mysqldump akzeptiert eine Liste von Tabellen aus einer Datenbank. Man müßte nur diese Liste ein wenig ausdünnen… Das folgende ist in php geschrieben, um die erweiterten Stringverarbeitungsfunktionen zu nutzen:

#!/usr/bin/php
<.?php
echo "#!/bin/bash\n";
echo "mysqldump -e -C --add-drop-table -u root --password=kennwort -h 127.0.0.1 ".$argv[1]." ";
$connection = mysql_connect("127.0.0.1", "root", "kennwort");
if (!$connection) {
    die("Fehler bei der Datenbankverbindung");
}
mysql_select_db($argv[1]);
$res = mysql_query("SHOW TABLES");
while( $row = mysql_fetch_row($res) ) {
  $table = $row[0];
  if (!(
    substr($table,0,6) == "cache_" ||
    substr($table,0,6) == "index_" ||
    substr($table,0,16) == "cachingframework"
  )) {
    echo $table." ";
  }
}

Dieses Script sichert nicht, es ist „quick+dirty“, also eklig geschrieben – aber es erstellt ein kurzes Shellscript, welches die Sicherung dann fortführt. Es erstellt eine Liste der Tabellen in einer angegebenen Datenbank, übergeht alle Zeilen, die mit „cache_“, „index_“, oder „cachingframework“ beginnen und gibt das erzeugte Script auf der Konsole aus, also bitte die Ausgabe in eine Datei umleiten. Und nicht vergessen, ein „chown 700“ auf diese Ausgabe anzuwenden.

Ich hoffe, daß dieser Artikel allen geplagten Heimanwendern ein paar gute Ansätze für eigene Sicherungsscripts gibt.