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.

Synchronize Workflow

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:

Automator Workflow 1

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:

Automator Workflow 2

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