Systemvoraussetzung
- Linux
- PHP 4 >= 4.3.0
- PHP 5
- MySQL
- Sed (StreamEditor)
- wahlweise ZIP, BZIP2, TARGZ
Datei(en)
backupDB.php
Problem
Sicherlich kennen Sie das Problem oder wurden in Ihrer Zeit als Programmierer
das ein oder andere Mal mit dieser Situation konfrontiert: Man verlangt von
Ihnen ein aktuelles Backup der MySQL-Datenbank,
da sämtliche Datenbankinhalte
weg sind. Jetzt ist guter Rat teuer, vor allem dann, wenn nur sehr selten
oder unregelmäßig Backups der Datenbanken durchgeführt wurden.
Stellen Sie sich den möglichen finanziellen Schaden vor, der entstehen kann,
wenn alle Daten unwiderruflich weg sind – das passiert schneller, als Ihnen
lieb ist, und immer genau dann, wenn man es am wenigsten gebrauchen kann.
Hinweis
Sollte das Skript, nachdem Sie es ausgeführt haben, keine Backupdatei erzeugen,
lesen Sie bitte den Text zu Verzeichnisrechten im einleitenden Teil
„Grundlegende Informationen“ in diesem Kapitel. Höchstwahrscheinlich wird
es dann daran liegen, dass Sie nicht die erforderlichen Rechte für dieses
Verzeichnis besitzen und diese erst vergeben müssen.
Gewöhnen Sie sich an, regelmäßige Backups durchzuführen und diese nach
Datum und Uhrzeit zu speichern. So werden Sie in der Lage sein, bestimmte
Backups zu einem bestimmten Ereignis liefern zu können. Eine schöne Vorstellung,
aber an der Umsetzung hapert es sehr oft – entweder wurden nie
Backups erstellt oder das letzte Backup ist drei Monate alt.
Lösung
Das nachfolgende Beispiel realisiert ein MySQL-Backup
Ihrer Datenbank über
die Shell, komprimiert die Backupdatei wahlweise als ZIP, BZIP2 oder TARGZ
und speichert die fertige Backupdatei mit einem Datum-/
Zeitstempel auf Ihrem
Server. Sie können diese Backupdatei weiterbearbeiten, z. B. per FTP auf einen
entfernten Backup-Server
spielen oder die Backupdatei per E-Mail
versenden.
Zum Schutz bei einem späteren Einlesen der Backupdatei wird beim Erstellen
des Backups eine Log-Datei
angelegt, die eine Prüfsumme für eine Integritätsprüfung
ermittelt und speichert. Vor dem Einlesen kann man nun überprüfen,
ob es sich um die Original-Backupdatei
handelt.
Konfiguration
Vervollständigen Sie die benötigten Parameter in der Konfiguration mit den
Werten für Ihre MySQL-Datenbank.
Sie sollten unbedingt für die Backup-Dateien
ein eigenes Verzeichnis anlegen, damit nicht versehentlich andere gepackte
Dateien mit gelöscht werden.
Die Integritätsprüfung der einzelnen Backupdateien benötigen Sie erst wieder
beim Einlesen der Dateien in die Datenbank. Vielleicht möchten Sie ja die
Backups auf einen entfernten FTP-Server
speichern, diese dann bei Bedarf
automatisch wieder holen und einlesen. Beim Einlesen wird dann überprüft,
ob es sich um die Originaldatei handelt.
|
<?PHP
// Datenbank Hostname oder IP
$self_config['dbhost'] = 'localhost';
// Datenbank Username $self_config['dbuser'] = 'dbuser';
// Datenbank Passwort $self_config['dbpassword'] = 'dbpassword';
// Datenbank Name $self_config['dbname'] = 'dbname';
// ZIP-Format ('zip' , 'bzip2' , 'targz') $self_config['zipformat'] = 'zip';
// Datei-Präfix der Backupdateien $self_config['praefix'] = $self_config['dbname'];
// Backupverzeichnis $self_config['dir'] = 'backup/';
// Alte Backups nach x Tagen löschen // Löscht alle Backups, die älter als der angegebene Wert sind! $self_config['delete'] = 14;
// Integritätsprüfung vornehmen? - TRUE / FALSE // Wird beim spaeteren Einlesen der Backupdatei genutzt $self_config['checkfile'] = TRUE;
// Name der Log-Datei für Integritätsprüfung $self_config['logfile'] = 'logfile.log';
|
Beispiel 8.1: backupDB.php
Hier beginnt der eigentliche Programmcode. Sie sollten den Code nur dann ändern,
wenn Sie wirklich wissen, was Sie tun. Sie sollten sich bewusst sein, dass
der Programmcode nicht nur Löschfunktionen, sondern auch Shell-Befehle
enthält.
Sollten Sie diesem Programmcode Benutzereingaben übergeben, prüfen
Sie diese genau, bevor diese Eingaben eventuell an die Shell mit übergeben
werden und Schaden anrichten könnten!
| $zip_format['zip'] = 'zip';
$zip_format['bzip2'] = 'tar.bz2'; $zip_format['targz'] = 'tar.gz';
|
Backupverzeichnis erstellen
Um das direkte Auslesen des Verzeichnisses zu verhindern, wird hier das
Backupverzeichnis auf das Recht 700 gesetzt. Dieses stellt einen Schutz Ihrer
Backupdateien dar.
| if(!is_dir($self_config['dir']))
mkdir($self_config['dir'], 0700);
|
Dateinamen bilden
Der Dateiname wird aus dem Datenbanknamen, gefolgt von dem aktuellen
Datum und der Uhrzeit gebildet.
Beispiel $dateiName: db152878808_20060307_
084948.
sql
Beispiel $tarName: db152878808_20060307_
084948.
tar.bz2 |
| $timeBackup = date("Y-m-d_H-i-s");
$dateiName = $self_config['dir'] . $self_config['praefix'] . '_' . $timeBackup . '.sql';
$tarName = $self_config['dir'] . $self_config['praefix'] . '_' . $timeBackup;
$crcpraefix = $self_config['praefix'] . '_' . $timeBackup . '.';
|
Überprüfung, ob Sed installiert ist
Hier findet lediglich eine Überprüfung statt, ob Sed auf Ihrem Server installiert
ist. Sollte das nicht der Fall sein, so wird die Backupdatei mit Kommentarzeilen
gespeichert. Da eine MySQL-Datei
sehr groß werden kann, ist es ratsam, die
Kommentarzeilen nicht über PHP entfernen zu lassen, sondern dies von einer
geeigneten Serversoftware erledigen zu lassen.
| $sedinstall = TRUE;
exec("whereis sed",$whereis);
if($whereis[0] == "sed:") $sedinstall = FALSE;
|
Backup der Datenbank
Führt das Backup der Datenbank aus. MySQL hat die Angewohnheit seine
eigenen erstellten Kommentare in einem Dump beim Einlesen als Fehler zu
interpretieren. Aus diesem Grund entfernen wir die Kommentare mit SED.
Somit kann unser Backup wieder ohne Probleme eingelesen werden. Der Dump
wird in das aktuelle Backupverzeichnis kopiert und nach dem Komprimiervorgang
gelöscht.
Z. B. als db152878808_20060307_
084948.
sql |
Beispiel der Kommentarzeilen
-- MySQL
dump 10.10
--
-- Host:
localhost Database: db152878808
-- ---------------------------------------------
-- Server
version4.0.25standard |
| $mysqlDump = 'mysqldump ';
$mysqlDump .= $self_config['dbname'] . ' '; $mysqlDump .= '--host="' . $self_config['dbhost'] . '" '; $mysqlDump .= '--user="' . $self_config['dbuser'] . '" '; $mysqlDump .= '--password="' . $self_config['dbpassword'] . '" ';
if($sedinstall)
$mysqlDump .= '| sed "s/^--.*$//" > ' . $dateiName; else $mysqlDump .= '> ' . $dateiName; exec($mysqlDump);
|
Backupdateien komprimieren
Man komprimiert die zuvor erstellte DumpDatei
(*.sql) und speichert diese in
das in der Konfiguration angegebene Format (zip, bzip2 oder tar.gz).
- -j filtert das Archiv durch bzip2
- -z filtert das Archiv durch gzip
- -c erstellt ein neues Archiv
- -f erstellt eine Archivdatei
| if($self_config['zipformat'] == "zip")
{ $tarName .= '.' . $zip_format[$self_config['zipformat']]; $shellBefehl = "zip -r $tarName $dateiName"; exec($shellBefehl); } else if($self_config['zipformat'] == "bzip2") { $tarName .= '.' . $zip_format[$self_config['zipformat']]; $shellBefehl = "tar -jcf $tarName $dateiName && bzip2 $tarName"; exec($shellBefehl); } else { $tarName .= '.' . $zip_format[$self_config['zipformat']]; $shellBefehl = "tar -zcf $tarName $dateiName && gzip $tarName"; exec($shellBefehl); } |
Löscht man dann die zuvor erstellte nicht komprimierte Backupdatei (*.sql),
geht man das komplette Backupverzeichnis durch und löscht alle Backups,
die älter als x Tage sind – der Wert für die Tage wird in der Konfiguration
festgelegt.
| $fileEnd = $zip_format[$self_config['zipformat']];
foreach($zip_format as $fileEnd) { foreach (glob($self_config['dir']."*".$fileEnd) as $filename) { $fileDate = (time() - filectime($filename))/60/60/24; if ($fileDate > $self_config['delete']) unlink($filename); } } |
Die Integritätsprüfung erstellt anhand der komprimierten Backupdatei eine
Prüfsumme (MD5-Code)
und speichert den 32 Zeichen langen Hexadezimalwert
in die Log-Datei.
Vor dem Einlesen in die Datenbank kann anhand dieses Wertes
geprüft werden, ob es sich um die Original-Backupdatei
handelt.
Form der Backupdatei
db152878808_20060307_
084948.
tar.bz2|11d63563dd055a9314f30b4f46893401
db152878808_20060308_
172651.
tar.bz2|89d9d2a2103ea24885de8c3a639b40ec |
| if($self_config['checkfile'])
{
$crc = md5_file($tarName); $crcString = $crcpraefix . $zip_format[$self_config['zipformat']] . '|' . $crc . "\n"; $fp = fopen($self_config['logfile'],"a"); fputs($fp,$crcString); fclose($fp);
}
?>
|
Dieses Skript aus dem SELFPHP KOCHBUCH wurde von SELFPHP unter dem "Tarif Mc500" von McAc.net-Webhosting erfolgreich ausgeführt und getestet!
Auf der Übersichtseite unter "McAc.net – Webhosting zu diesem Buch" finden Sie weitere Informationen zu dem Webhostingpaket, dass durch SELFPHP getestet wurde.
|