Artikel mit dem Tag "MySQL"

MySQLDu in neuer Version 1.1

Meine kleine MySQL-Backup-Lösung MySQLDu gibt es in der neuen Version 1.1.

Neben zwei kleinen Änderungen ist die neu hinzugefügte FTP-Unterstützung interessant. Backups können jetzt automatisch auf einen FTP-Server hochgeladen werden.

MySQLDu 1.1 herunterladen

Share
Geschrieben von Philip Ehret am 16.08.2010 | Kommentare weiterlesen...

Automatisches MySQL-Backup per Mail

Wem seine Daten lieb sind, der sichert sie häufig. Ob Wöchentlich, täglich oder stündlich hängt dabei von der Änderungsrate ebendieser ab, völlig unabhängig davon ist aber, dass die manuelle Erstellung von Backups kostbare Zeit kostet, die anderweitig besser investiert wäre.

Bei Internetprojekten ist die frei verfügbare MySQL-Datenbank mittlerweile ein Standard, administriert wird sie meistens mit phpMyAdmin, einem ebenso kostenlosem Web-Interface. Wer MySQL-Datenbanken normalerweise sichert, der erstellt in phpMyAdmin ein Datenbank-Dump und lässt es sich wahlweise als Textdatei oder in einem Archiv verpackt liefern. Doch aufgrund der nötigen Autorisierung am Server dauert die Erstellung schon einige Zeit, wieso da nicht einfacher? Mit einem automatischen Backup zum Beispiel.

Mithilfe eines Cronjobs, dem Tipp, wie man mit wget ein PHP-Script aufruft und MySQLDu lässt sich einfach eine Backup-Lösung erstellen. Wie das geht wird im Folgenden erklärt.

Laden wir zunächst die aktuelle Version von MySQLDu (1.0) herunter und entpacken das Archiv auf den Webserver, auf dem auch die MySQL-Datenbank liegt.

Als nächstes löschen wir die Dateien testoutput.php, testmail.php, testfile.php, msdu.sql und das Unterverzeichnis dump/, da diese entweder zu Testzwecken dienen oder für die Sicherung per Mail nicht erforderlich sind.

Ganz wichtig ist, dass das Unterverzeichnis tmp/ durch den Webserver-Benutzer schreibbar ist (am Besten setzen Sie die Rechte auf 0777).

Jetzt erstellen wir eine neue Datei cronbackup.php mit folgendem Inhalt:

<?php
	define("MYSQLDU_MODE","mail"); // legt den Mail-Modus fest

	// Datenbankzugangsdaten
	define("MYSQLDU_DB","");
	define("MYSQLDU_USER","");
	define("MYSQLDU_PASSWORD","");
	define("MYSQLDU_HOST","localhost");	

	// Mail-Optionen
	define("MYSQLDU_MAIL_FROM","noreply@philip-ehret.de");
	define("MYSQLDU_MAIL_FROMNAME","MySQLDu V!version");
	define("MYSQLDU_MAIL_TITLE","MySQL dump of !database on !d.!m.!Y (!H:!i:!s)");
	define("MYSQLDU_MAIL_TEXT","Hi there, this mail contains your dump of database !database created by MySQLDu V!version on !d.!m.!Y (!H:!i:!s).\n".
		"See attached file!\n\n".
		"Thanks for using MySQLDu (http://philip-ehret.de/projekte/mysqldu/)\n".
		"See also mysqldump.php from Huang Kai (http://atutility.com/software/mysqldumpphp/) on which MySQLDu is based on\n".
		"This mail was automatically generated and sent by PHPMailer(http://phpmailer.worxware.com/)");
	define("MYSQLDU_MAIL_SENDTO","mail@philip-ehret.de");
	define("MYSQLDU_MAIL_ATTACHMENT_NAME","!server.!database.!date.dump.sql");

	require_once("mysqldu-1.0.php");
?>

Wichtig ist, dass Sie die Konstanten MYSQLDU_USER, MYSQLDU_HOST, MYSQLDU_PASSWORD, MYSQLDU_DB an die Zugangsdaten Ihrer MySQL-Datenbank anpassen und MYSQLDU_MAIL_FROM und MYSQLDU_MAIL_SENDTO passend setzen (Das erste ist die E-Mail-Adresse, die später als Absender der Backup-Mail erscheint, das zweite die E-Mail-Adresse, an die das Backup gesandt werden soll).

Die Konstanten MYSQLDU_MAIL_TITLE und MYSQLDU_MAIL_TEXT können Sie nach belieben anpassen, mögliche Platzhalter finden Sie in der mysqldu-1.0.php in der Variablen $MYSQLDU_REPLACE_ARRAY.

Rufen Sie das Script jetzt einmal mit Ihrem Browser auf. Die Ausgabe sollte bei Erfolg die folgende sein. Eventuell öffnet Ihr Browser auch einen Download-Dialog, die heruntergeladene Datei enthält dann die Ausgabe.

{"status":"success","text":"Mail was successfully delivered"}

Es handelt sich hierbei um eine JSON-codierte Ausgabe. Das ist deswegen so, damit andere Scripte, die das Backup-Script aufrufen könnten, die Rückmeldungen einfach verarbeiten können.

Sollten Sie eine andere Ausgabe erhalten, so sehen Sie sich den JSON-codierten Fehlertext an. Dieser gibt Rückschlüsse darauf, was falsch läuft. Überprüfen Sie die Schreibrechte für das Unterverzeichnis tmp/ und stellen Sie sicher, dass Sie die Datenbankzugangsdaten korrekt eingegeben haben.

Wenn die Ausgabe stimmt, gehen Sie in das E-Mail-Postfach der für MYSQLDU_MAIL_SENDTO angegebenen E-Mail-Adresse. Dort sollte bereits eine E-Mail auf Sie warten, welche die Datenbanksicherung als Anhang enthält.

Um das E-Mail-Backup jetzt auch noch vollautomatisch zu erhalten, führen Sie sich den Artikel zur Ausführung eines PHP-Scriptes mithilfe eines Cronjobs zu Gemüte, welcher nicht nur für Plesk seine Gültigkeit hat.

Meine persönlichen Datenbanken sind zum Großteil in Unicode, da das etliche Vorteile bietet, welche den gegenüber anderen Datencodierungen höheren Speicherverbrauch meiner Meinung nach durchaus rechtfertigen.
Sollten Sie eine andere Codierung haben und die Dump-Datei fehlerhaft sein, versuchen Sie das Problem zu beheben, indem Sie an den Anfang der cronbackup.php folgenden Code einfügen:

define("MYSQLDU_UTF8",0);
Share
Geschrieben von Philip Ehret am 13.08.2010 | Kommentare weiterlesen...

MySQL UPDATE unter Einbeziehung des aktuellen Feldwertes

Da in einer meiner Projektdatenbanken für Bilder relative Pfade verwendet werden und ich die lokale Version des Projekts in einem Verzeichnis pflege, dessen Name nicht dem der Online-Version entspricht, war es notwendig, alle Pfade in der lokalen Projektdatenbank anzupassen.

Während der Projektpfad online

/projectx/

lautete, hieß er lokal

/domainx/projectx/

Das Anpassungsscript sollte also den aktuellen Feldwert nehmen und davor ein /domainx einfügen.
Leider funktioniert das nicht ähnlich simpel wie mit Zahlen, bei denen der aktuelle Feldwert einfach mit einem mathematischen Operator wie z.B. einem + mit einer Zahl verknüpft werden kann, wie etwa hier:

UPDATE `tablex` SET `fieldx` = `fieldx` + 5

Es muss vielmehr auf die MySQL-Funktion CONCAT zurückgegriffen werden, welche alle Argumente zu einem String verknüpft.
Das sah in meinem Fall dann so aus:

UPDATE `tablex` SET `fieldx` = CONCAT('/domainx', `fieldx`)

Wichtig ist, dass die Argumente für CONCAT richtig angegeben werden: Auf Feldwerte wird mit dem Feldnamen bzw. dem durch gequoteten Feldnamen Bezug genommen, direkte Stringeingaben erfolgen durch einfache Hochkommas.

Share
Geschrieben von Philip Ehret am 08.03.2010 | Kommentare weiterlesen...

MySQL Union: Mehrere Tabellen verbinden, erfahren aus welcher Tabelle Datensatz stammt

Das zugrunde liegende Problem war in diesem Fall, dass ein News-Bereich in mehrere Sektionen unterteilt sein sollte: Aktuelles, Presse, Events. Jede Sektion erhielt eine eigene Tabelle, weil die jeweiligen Datensätze sich geringfügig unterschieden (in der Presse-Sektion gab es immer eine Quelle, in der Events-Sektion eine URL für einen externen Link,..) und um bei den vielen Datensätzen die Lesezeiten so klein wie möglich zu halten (befindet sich ein Benutzer in der Pressesektion, ist es unnötig, auch die Aktuelles- und Events-Datensätze zu durchforsten).

Jedoch sollte auf der Startseite des Projekts eine Art Newsticker eingefügt werden, welcher die aktuellsten fünf Datensätze anzeigt. Das bedeutet, dass aus allen drei Tabellen gelesen und nach einem Zeitkriterium geordnet werden muss. In meinem Fall ist die Zeit in jeder Tabelle im Feld `time` als Timestamp gespeichert. Meine Abfrage, um alle drei Tabellen einzubeziehen, lautet unter Verwendung von MySQL UNION:

(SELECT `id`, `time`, `title` FROM `aktuelles`) UNION (SELECT `id`, `time`, `title` FROM `presse`) UNION (SELECT `id`, `time`, `title` FROM `events`) ORDER BY `time` DESC LIMIT 5

Um die Problematik zu verstehen, die jetzt kommt, ist ein Blick auf die Seitenstruktur des Projekts hilfreich:

  • Startseite (startseite.html)
  • News (news.html)
    • Aktuelles (news/aktuelles.html)
    • Presse (news/presse.html)
    • Events (news/events.html)

Klickt der Benutzer den „weiterlesen…“-Link im Newsticker auf der Startseite, soll er direkt in die entsprechende News-Sektion springen. Dazu muss aber bekannt sein, aus welcher Tabelle der entsprechende Datensatz stammt. Das lässt sich wie folgt umsetzen:

(SELECT 'aktuelles' AS `tbl`, `id`, `time`, `title` FROM `aktuelles`) UNION (SELECT 'presse' AS `tbl`, `id`, `time`, `title` FROM `presse`) UNION (SELECT 'events' AS `tbl`, `id`, `time`, `title` FROM `events`) ORDER BY `time` DESC LIMIT 5

So einfach lässt sich die Herkunft der Datensätze unterscheiden: In den Ergebnissen der Abfrage erscheint nun ein Feld `tbl`, das den Namen der Herkunftstabelle enthält.

Share
Geschrieben von Philip Ehret am 02.10.2009 | Kommentare weiterlesen...