Automator-Transmit-MySQLdump-Backup-Lösung
Die erste Aufgabe meines Praktikums bei Gerrit war es, mir eine Backup-Lösung für alle seine Kunden auszudenken. Es sollten sowohl die MySQL-Datenbank, als auch alle Dateien gesichert werden. Die Schwierigkeit hierbei ist es, dass Gerrits Kunden bei verschiedensten Hostern untergebracht sind. Dies bereitete für das Datenbank-Backup einige Probleme.
MySQL-Backup
Ich habe vieles ausprobiert. Von shell_exec(dump_foobar) bis hin zu mächtigen Tools wie dem MySQLDumper. Doch entweder liefen diese nicht auf den verschiedenen Hostern oder konnten nicht durch einen einfachen URL-Aufruf ausgelöst werden.
Erst nach dem Tweet von Gerrit hatten wir hierfür eine Lösung: Der nette Markus Unterwaditzer hatte ein kleines php-script geschrieben, was wir noch etwas ergänzten und nun perfekt für uns funktioniert. Es wird durch einen URL-Aufruf ausgelöst und schreibt dann eine MySQL-Dumpdatei auf den entsprechenden Server.
FTP-Backup
Die erste Wahl für Automatisierungs-Aufgaben ist bei mir der von allen unterschätzte Automator von Mac OS X. Transmit bietet seit seinem Sprung auf Version 4 nun auch Workflows für diesen an.

Perfekt hierfür wäre der Synchronize-Workflow, der aktuell leider mit einem Bug behaftet ist und somit leider nicht funktioniert. (Trotz korrektem RemotePath gibt es einen CHDIR-Fehler, und es wird abgebrochen.)
Deswegen vorerst der Umweg über den Download-Workflow.
Automator-Action
Um nun alles auf einmal zu haben, bastelt man ein wenig im Automator:

Zuerst sollte das MySQL-Backup ausgeführt werden. Hier muss man ein wenig mit dem Text einer Webseite abfragen-Workflow tricksen. Dieser öffnet die ihm übergebene URL im Hintergrund, ohne ein Browserfenster dabei zu öffnen. Man gibt dem Server noch eine kleine Verschnaufpause (zur Sicherheit) und lädt dann alle Dateien herunter.
multikundenbackup
Hat man mehrere Kunden, lohnt es sich, einen Automator-Workflow pro Kunde einzurichten. Diese bringt man anschließend alle nacheinander in einem weiteren Workflow zur Ausführung:

TimeMachine
Unser Ziel ist es, am Ende eines Arbeitstages den Automator zu starten, und dann in den verdienten Feierabend zu gehen, während die Technik den Rest erledigt. Im Zusammenspiel mit TimeMachine ist das Ganze dann auch inkrementell und auf einer externen Festplatte gesichert.
Kann quasi nichts mehr schief gehen!?
Das Script
$starttime = time();
$startmem = memory_get_usage();
//Config
$dbhost = "localhost";
$dbuser = "user";
$dbpwd = "pw";
$dbname = "dbname";
$conn = @mysql_connect($dbhost, $dbuser, $dbpwd);
if (!$conn) {
die("Datenbankverbindung fehlgeschlagen!");
}
mysql_select_db($dbname);
//SQL Dump
$f = "";
$tables = mysql_list_tables($dbname);
while ($cells = mysql_fetch_array($tables)) {
$table = $cells[0];
$f .= "DROP TABLE IF EXISTS `$table`;\n";
$res = mysql_query("SHOW CREATE TABLE `$table`");
if ($res) {
$create = mysql_fetch_array($res);
$create[1] .= ";";
$line = str_replace("\n", "", $create[1]);
$f .= $line."\n";
$data = mysql_query("SELECT * FROM `$table`");
$num = mysql_num_fields($data);
while ($row = mysql_fetch_array($data)){
$line = "INSERT INTO `$table` VALUES(";
for ($i=1;$i<=$num;$i++) {
$line .= "'".mysql_real_escape_string($row[$i-1])."', ";
}
$line = substr($line,0,-2);
$f .= $line.");\n";
}
}
}
// Write Dump
$myFile = "dump.sql";
$fh = fopen($myFile, 'w') or die("can't open file");
if ( fwrite($fh, $f) ) {
echo date('Y-m-d H:i:s')." — Successfully written dump
";
echo "Zeitverbrauch: ".(time()-$starttime)."
";
echo "Memoryusage: ".((memory_get_usage()/1024)-($startmem/1024))."kB";
} else {
echo "Something went wrong while writing dump file.";
}
fclose($fh);
Mit nochmaligem Dank an Markus Unterwaditzer
Gerrit am 1. September 2010 #
Das Tolle daran: Sowohl die Backup-Ordner, als auch die ganzen Automator-Skripte liegen auf der externen Platte. Man kann die Backup-Action also mit jedem beliebigen Mac durchführen, der über Transmit 4 verfügt. Platte über USB anschließen, das Haupt-Automatorskript ausführen und los geht’s!
Stefan am 1. September 2010 #
Kleine Anmerkung: bei groesseren Datenbanken koennte das Script ganz schnell zu viel Arbeitsspeicher verbrauchen, da die ganzen Daten erst in einer Variable landen. Besser direkt vorher Datei schreibend oeffnen und dann direkt in die Datei schreiben.
Matt am 1. September 2010 #
Backups sollten idealerweise ohne menschlichen Eingriff funktionieren. Denn Murphy hat es nur darauf abgesehen, dass man das Backup vom Vortag dann braucht, wenn man es vergessen hat zu machen.
Gerrit am 1. September 2010 #
@Stefan: Meine praegnanz-Datenbank ist 43 MB groß – und das Gros meiner Kunden hat deutlichst kleinere Datenbanken. Bisher war das kein Problem – wir haben die Speicherauslastung ja im Blick. Sollte es Probleme geben, denken wir an deinen Vorschlag!
nasumi am 1. September 2010 #
Was mich bei dieser Lösung etwas stört ist die Tatsache, dass jemand daran denken muss das Script auszuführen.
Ich fände es sinnvoller, anstelle eines Automatorscripts, einen Cronjob auf einem Server einzurichten der immer online ist. Der Cronjob könnte dann die Aufgaben nächtlich abarbeitet und die Backupdaten dann z.B. bei einem entsprechenden Onlinedienst gespeichert werden.
Michael am 1. September 2010 #
Solche Backupstrategien, die auf lokalen Rechnern installiert sind, taugen meiner Meinung nach nicht viel. Ich hatte immer wieder Probleme, dass Rechner auch mal ausgetauscht werden oder einfach aus sind oder durch Updates die Skripte nicht mehr funktionieren. Ein paar Wochen lief alles, dann funktionierte irgend was nicht mehr und im schlimmsten Fall habe ich es noch nicht mal gemerkt. Und manuelles Starten des Backups geht ja nun mal gar nicht ;-)
Die beste Lösung ist m.E. einen Backup-Webserver in einem Rechenzentrum einzurichten. Dort laufen dann PHP-Scripte (ich bin halt PHP-Entwickler, kann man natürlich auch anders machen) und ich bekomme jeden Tag eine E-Mail mit dem Protokoll.
stk am 1. September 2010 #
Falls der allererste Job auf irgendeine Art und Weise haengen bleibt, war’s das aber auch mit dem Rest der Backups fuer den Abend, oder?
Also beispielsweise, falls das RZ brennt, Rechner 1 schon abgefackelt ist, Rechner 2 bis 10 aber noch zu sichern waeren ;)
Gerrit am 1. September 2010 #
Selbstverständlich ist der Plan, eine dedizierte Maschine für das Backup abzustellen, der das Automator-Script täglich abfeuert, ohne, dass man etwas dafür tun muss. Jetzt ging es erstmal darum, überhaupt eine One-Click-Lösung zu bauen, die alle Projekte automatisch abarbeitet und sowohl Dateien als auch Datenbank enthält.
Peter am 1. September 2010 #
Beim PHP-Skript auf die Kodierung der Datenbank-Verbindung achten. Je nachdem, wie hier PHP eingestellt ist, wird das Backup sonst mit ISO oder mit UTF-8 geschrieben. Ein richtiger Dump wäre vorzuziehen.
Ich empfehle die Trennung von DB-Backup und FTP-Backup. DB-Backup als PHP-Script wie hier – oder als Shellscript wenn möglich, gesteuert über Cronjob. Kostenlose oder billige Cron-Dienste gibts in Massen. Das hat den Vorteil, dass das DB-Backup in jedem Fall mal auf die Server-Platte geschrieben wird, auch wenn der ganze Rest des Backups mal ausfällt. Die Datanbank ändert sich häufiger und ist viel schwerer zu rekonstruieren.
Ich würde die Automator-Aktionen zeitversetzt starten und unabhängig, ist sicherer. iCal müsste das doch können, oder? Ansonsten ein Shell-Script.
Allerdings präferiere ich einen anderen Workflow.
Mein Problem mit Transmit ist, dass das Teil immer den kompletten Download abbricht, wenn es zu einem Lesefehler auf dem Server kommt. Da das aufgrund von Rechte-Änderungen jederzeit passieren kann, war mir diese Lösung schlicht zu riskant, mir ist es immer wieder passiert, dass Transmit nicht zuende geschrieben hat. Ich halte Transmit als reinen FTP-Client für unzuverlässig. Transmit hat andere Stärken, in der täglichen Arbeit direkt auf dem Server ist es unschlagbar. Aber Backups – nein.
Ich bin deshalb auf AbleFTP gegangen. Das Teil hat eine schreckliche GUI (wie viele Java-Anwendungen) aber erlaubt einen zuverlässigen, zeitgesteuerten – und vor allem inkrementellen – FTP Download. Es können auch Ausschlusskriterien definiert werden, was wichtig ist, da ich z. B. nicht den Quellcode von TYPO3 oder von phpMyAdmin backupen will. Es kostet zwar was, aber das ist es auch wert.
Mein Workflow sieht so aus:
- DB-Backups auf jedem Kundenserver, in der Regel über Shellscript. – Jede Nacht via AbleFTP ein FTP-Backup, auf einem eigenen Rechner (mein fileserver, der die ganze Nacht läuft) – Sicherung desselben via Timemachine. – Da darauf die ganzen Kundendaten liegen, wird das nochmals abgesichert, indem täglich die Timemachine-Platte getauscht wird.
Das Ganze ist auch ein Datenschutzproblem: die Backups enthalten die Zugangsdaten und u. U. weitere vertrauliche Daten, deshalb haben die nichts auf den Arbeitsplatzrechnern zu suchen. Der Server sollte deshalb nur für Leute zugänglich sein, die entsprechende Verträge unterschrieben haben.
Gruß
Peter
Gerrit am 1. September 2010 #
Shellscripte sind schön und gut. Aber 90% meiner Kunden sind bei einem Billighoster für 4 Euro im Monat untergebracht – reicht ja auch für deren Anforderungen. Hier muss man sich mit PHP-Skripten behelfen.
Was die Zuverlässigkeit von Transmit angeht – das muss man eben ausprobieren, ob’s so geht.
Meerblickzimmer am 1. September 2010 #
Interessante Diskussion, die eigentlich ein Problem als Ausgang hat: 90% deiner Kunden sind bei Billighostern.
Da hab ich zum Glück von Anfang an nen Riegel vorgeschoben und Hoste alles »selber«. So weiss ich was alles auf dem Server ist, kann ggf. Serveranpassungen machen und Backupen geht auch viel viel einfacher.
Deine Lösung ist noch handelbar für nen handvoll Installationen. Aber irgendwann wird selbst der »Verwalten« solcher manuellen Scripte zur Herausforderung (Kunde zieht um zu nem anderen Hoster, Hoster ist Pleite … alles nach vielen Jahren und du bekommst es kaum mit, Kunden ändern aus was für Gründen auch immer nen Passwort …).
Gerrit am 2. September 2010 #
@Meerblickzimmer: Meine Kunden wissen zum Großteil nicht mal, was ein Hoster genau ist, sondern haben sich 2003 mal für Strato oder 1&1 beschwatzen lassen und sich seitdem nie mehr eingeloggt. Die Gefahr, dass hier Passwörter geändert werden ist gering :-)
Frank am 2. September 2010 #
OK, »freakigere« UNIX-Tools, aber Transmit wäre auch durch wget oder rsync ersetzbar. Soweit ich mich entsinne, kann der Automator auch Shellscripte feuern.
Und für die Jungs, die Windows-Maschinen haben: Das geht auch damit, kombiniert mit Cygwin und dessen Cron-Dienst. Das sind allerdings Dinge, die vielen nicht-Shell-Nutzern nicht gefallen. Daher haben natürlich andere Backupprogramme eine Berechtigung.
Und wer Timemachine oder einer anderen externen Plattenlösung nicht traut: Ich nutze seit geraumer Zeit ein Strato-Highdrive in Kombination mit rsync. Läuft prima.
Konrad am 5. September 2010 #
Bei mir laufen Backups komplett automatisch. Ich sichere dabei aber nur die Datenbank und keine Dateien auf dem Webserver, da sich die in meinem Fall recht selten ändern. Auf jedem Server liegt ein kleines Script das jeden Tag die Datenbank sichert. Ein Backup Server holt sich das dann ab und speichert das. Jede Woche oder so ziehe ich mir dann noch die Daten vom Backup Server.
Ist halt sehr unwahrscheinlich, dass Backup und jeweiliger Webserver gleichzeitig crashen / ausfallen. Hinzu kommt, dass einige meiner Hoster auch noch selbst Backups erstellen. Bisher bin ich mit dieser Lösung sehr gut gefahren…
Carsten am 6. September 2010 #
Wichtig ist auch sich immer einen Statusbericht erstellen oder Statusmail der Backups senden zu lassen. Sonst vertraut man nacher auf ein Backup was eventuell fehlerhaft war.
Friedrich am 7. September 2010 #
Die sicherste Methode ein Backup der MySQL Datenbank durchzuführen ist per SSH. Damit ist es auch möglich sehr große Datenbanken zu sichern. Das funktioniert unter Windows zum Beispiel mit Putty oder dem Terminal unter Mac OS X.
Geht nicht bei Billighostern, da oft kein SSH vorhanden.
mysqldump -uBENUTZERNAME -pPASSWORT -hlocalhost DB_NAME > DB_NAME.sql
Das ganze läßt sich auch mit gzip verpacken!
mysqldump -uBENUTZERNAME -pPASSWORT -hlocalhost DB_NAME | gzip > DB_NAME.sql.gz
Das Backup kannst anschließend mit z.B. Transmit auf die lokale Festplatte heruntergeladen werden.
Um das Backup über eine Datei in eine Datenbank zurückzuspielen, gibt es folgenden Befehl.
(Achtung, alle Daten werden dabei in der Datenbank überschrieben!)
mysql -uBENUTZERNAME -pPASSWORT -hlocalhost DB_NAME < DB_NAME.sql
Die Benutzername, Passwort etc. müssen natürlich entsprechend angepasst werden.
Robert am 8. September 2010 #
Jetzt habe ich mich nach dem Titel so auf den Beitrag gefreut, um dann feststellen zu müssen, dass man das mühsam zusammenscripten muss. Und selbst dann gibt es wie in den obigen Kommentaren erwähnt nachdenkenswerte Argumente zur Erweiterung. Und das bei einer so klassischen und wichtigen Aufgabe, die jeder Webseitenbetreiber eigentlich erledigen sollte?
Es gibt doch für jeden Schrott irgendein Tool, eine Software, die das kann. Da sollte es doch hierfür auch eine robuste Lösung geben, für die man nicht gleich ein halbes Rechenzentrum mieten muss, oder?
Friedrich am 8. September 2010 #
Hallo Robert,
es gibt auch Softwarelösungen. Dazu ist aber auch eine Möglichkeit erforderlich auf Datenbanken von AUSSEN zu zugreifen.
Schau mal hier:
Die Software kostet aber auch 99 Dollar!
http://www.site-vault.com/
Tim am 13. September 2010 #
Wow, es funktioniert. Danke!
hans am 20. September 2010 #
ich habe ein mini-script auf jeder seite das rufe ich im browser auf und bekomme ein backup der datenbank per mail zugesendet, wenn ich auf »alle in tabs öffnen« gehe hab ich gleich alle auf einmal. in mail hab ich dann die regel eingerichtet das diese mails in einem ordner verschwinden und als gelesen markiert werden. FTP backup mache ich 1x im jahr bei allen per hand, da passiert eh nicht viel.
Alex am 8. Dezember 2010 #
Hallo!
Sync mit Transmit per Automator geht prima. Der Remote-Path-Fehler kommt daher, dass Transmit den Remote Path aus dem gespeicherten Favoriten übernimmt. Wird dann im Automator zusätzlich nochmal der Remote Path eingetragen, dann meckert er…