Alex: mySQL - Dump - Zeichenkodierung und Dump über PHP system()

Hallo Leute,

ich lasse mit PHP über system() einen mysqldump erstellen. Dabei habe ich 20 Tabellen. Eine davon ist mit BLOBS gefüllt, in denen PDFs gespeichert sind. (Wieso ich das nicht anders mache, weiß ich auch nicht wirklich...aber das ist ein anderes Thema)

Frage 1:
Jedenfalls werden die Umlaute in der .sql Datei, wenn ich sie mit TotalCommander per FTP abrufe nicht richtig dargestellt (z.B. für den) wenn auch die BLOB-Tabelle gesichert wird. Sind es nur die 19 anderen klappt alles.
Bei der Bildschirmausgabe nach dem dump (per readfile()) sieht auch alles OK aus.

Nachdem ich überall geschaut habe, dass es die gleiche Zeichenkodierung ist, wusste ich nicht mehr was ich noch machen soll und habe einfach mal den dump ausprobiert. Es klappt. Sowohl die Umlaute als auch die gespeicherten PDFs funktionieren nach dem Restore noch. Auch wenn ich den Dump erst per FTP runterlade und ihn dann wieder hochlade.

Ich denke also das sollte sowei passen, auch wenn es halt am Computer im Editor komisch aussieht. Wie seht ihr das - könnte ich da irgendwo Probleme bekommen, oder passt das?

Frage 2:
Wenn ich mit phpMyAdmin einen Dump mache, (Ich lasse ihn immer im Textfeld anzeigen und kopiere das dann in eine UTF8-Datei) sieht das ganze durch die Zeilenumbrüche sehr aufgeräumt aus und man könnte sich zur Not auch in dem Dump zurechtfinden.
Kann ich das mit mysqldump auch irgendwie hinbekommen?

Frage 3:
Das Ganze soll ein Cronjob werden und muss daher selbstständig funktionieren. Ich möchte daher für jeden Fehler den es geben kann eine entpsrechende Lösung oder Mail-Benachrichtigung einbauen. Deshalb wollte ich über
if (system(mysqldump...))
abfragen, ob der dump geklappt hat. Leider kommt aber anscheinend immer FALSE heraus, obwohl die DB soweit ich erkennen konnte vollständig gesichert wurde.

Ich könnte im Anschluss testen, ob die Datei vorhanden ist - aber das Problem ist auch, dass ja bei einem Fehlerhaften Dump auch die Datei angelegt wird und eine Nachricht bzw. gar nichts drinnen steht.

Wie kann ich hier eine sinnvolle Prüfung machen?

Vielen Dank schon mal!

Gruß
Alex

  1. Hi!

    Jedenfalls werden die Umlaute in der .sql Datei, wenn ich sie mit TotalCommander per FTP abrufe nicht richtig dargestellt (z.B. für den) wenn auch die BLOB-Tabelle gesichert wird. Sind es nur die 19 anderen klappt alles.

    Beschäftige dich grundlegend mit dem Thema Zeichenkodierung. Das läuft nicht auf magische Weise von selbst. Der Sender muss dem Empfänger angeben, in welcher Kodierung er sendet. Wenn der Empfänger das nicht erfährt und seine Default-Einstellung falsch ist, kommt es zu Dekodierungsfehlern. Es ist jedoch nicht in jedem Fall vorgesehen, die Kodierung zur Datei zu speichern. Im Dateisystem geht diese Information verloren. Da kommt es darauf an, dass das öffnende Programm richtig rät oder gesagt bekommt, wie es die Datei zu interpretieren hat.

    In dem Fall sieht es so aus, als ob der TC davon ausgeht, er bekäme ISO-8859-1 (oder Windows-1252), tatsächlich ist es aber UTF-8. Dem mysqldump kann man einen Parameter mitgeben, der die gewünschte Zeichenkodierung angibt. Was anderes als UTF-8 führt jedoch eventuell zu Datenverlust, wenn Zeichen außerhalb der Möglichkeiten der gewünschten Kodierung vorhanden sind.

    Bei der Bildschirmausgabe nach dem dump (per readfile()) sieht auch alles OK aus.

    Hier wird es wohl, genauer betrachtet, so sein, dass PHP eine Ausgabe an einen Browser schickt, oder? Entweder hat der Browser zufällig richtig geraten oder er hat gesagt bekommen, welche Kodierung vorliegt.

    Nachdem ich überall geschaut habe, dass es die gleiche Zeichenkodierung ist,

    Definiere "überall".

    [...] habe einfach mal den dump ausprobiert. Es klappt. Sowohl die Umlaute als auch die gespeicherten PDFs funktionieren nach dem Restore noch. Auch wenn ich den Dump erst per FTP runterlade und ihn dann wieder hochlade.

    Wenn du keine Umkodierung vornimmst und auch weder beim Dump noch beim Einspielen eine explizite Kodierungsangabe angegeben hast, wird der Server seinen Default für beide Vorgänge nehmen, und alles wird gut.

    Ich denke also das sollte sowei passen, auch wenn es halt am Computer im Editor komisch aussieht. Wie seht ihr das - könnte ich da irgendwo Probleme bekommen, oder passt das?

    Sag dem Editor, welche Kodierung vorliegt.

    Wenn ich mit phpMyAdmin einen Dump mache, (Ich lasse ihn immer im Textfeld anzeigen und kopiere das dann in eine UTF8-Datei) sieht das ganze durch die Zeilenumbrüche sehr aufgeräumt aus und man könnte sich zur Not auch in dem Dump zurechtfinden.
    Kann ich das mit mysqldump auch irgendwie hinbekommen?

    Alles was du mit mysqldump hinbekommen kannst, steht in seiner Dokumentation. Hast du da mal nachgeschaut?

    Das Ganze soll ein Cronjob werden und muss daher selbstständig funktionieren. Ich möchte daher für jeden Fehler den es geben kann eine entpsrechende Lösung oder Mail-Benachrichtigung einbauen. Deshalb wollte ich über
    if (system(mysqldump...))
    abfragen, ob der dump geklappt hat. Leider kommt aber anscheinend immer FALSE heraus, obwohl die DB soweit ich erkennen konnte vollständig gesichert wurde.

    Kommt sicher false raus oder ist nur die letzte Zeile der Ausgabe eine Leerzeile, die auch als false erkannt wird? Ein typsicherer Vergleich mit === oder !== räumt Zweideutigkeiten aus dem Weg.

    Lo!

    1. Hallo,

      danke für deine Antwort!

      In dem Fall sieht es so aus, als ob der TC davon ausgeht, er bekäme ISO-8859-1 (oder Windows-1252), tatsächlich ist es aber UTF-8. Dem mysqldump kann man einen Parameter mitgeben, der die gewünschte Zeichenkodierung angibt. Was anderes als UTF-8 führt jedoch eventuell zu Datenverlust, wenn Zeichen außerhalb der Möglichkeiten der gewünschten Kodierung vorhanden sind.

      Ich habe jetzt im TotalCommander nochmal nachgeschaut und die Option UTF-8 gefunden. Jetzt klappt es auch mit den Umlauten. (Vorher hatte ich im Notepad schon probiert, als UTF-8 zu speichern, das hat aber nichts gebracht).
      Das heißt also, dass die Darstellungsprobleme wirklich nur an meinem Computer lagen nehme ich an?

      Bei der Bildschirmausgabe nach dem dump (per readfile()) sieht auch alles OK aus.

      Hier wird es wohl, genauer betrachtet, so sein, dass PHP eine Ausgabe an einen Browser schickt, oder? Entweder hat der Browser zufällig richtig geraten oder er hat gesagt bekommen, welche Kodierung vorliegt.

      War wohl eher Zufall. Die PHP-Datei selbst ist laut Dreamweaver ISO. Ansonsten wird nichts bezüglich der Codierung eingestellt. Im Firefox wird es als UTF-8 angezeigt...

      Nachdem ich überall geschaut habe, dass es die gleiche Zeichenkodierung ist,

      Standardkodierung von der Datenbank und Codierung der einzelnen Tabellen/Spalten. Und die entsprechenden Einstellungen in mysqldump.

      Wenn du keine Umkodierung vornimmst und auch weder beim Dump noch beim Einspielen eine explizite Kodierungsangabe angegeben hast, wird der Server seinen Default für beide Vorgänge nehmen, und alles wird gut.

      »»
      Gut :)

      Alles was du mit mysqldump hinbekommen kannst, steht in seiner Dokumentation. Hast du da mal nachgeschaut?

      Das habe ich schon vorher gelesen. Das einzige, was erfolgversprechend geklungen hat, war --result-file. Hat aber nichts geändert.

      Kommt sicher false raus oder ist nur die letzte Zeile der Ausgabe eine Leerzeile, die auch als false erkannt wird? Ein typsicherer Vergleich mit === oder !== räumt Zweideutigkeiten aus dem Weg.

      Das verstehe ich leider nicht.

      Wenn ich var_dump(system("mysqldump...")) mache bekomme ich string(0) ""
      Bei var_dump() vom Output von system bekomme ich int(0)

      Vielleicht kannst du mir da nochmal einen kleinen Tipp geben - danke schomal!

      Gruß
      Alex

      Lo!

      1. Hi!

        Ich habe jetzt im TotalCommander nochmal nachgeschaut und die Option UTF-8 gefunden. Jetzt klappt es auch mit den Umlauten. (Vorher hatte ich im Notepad schon probiert, als UTF-8 zu speichern, das hat aber nichts gebracht).
        Das heißt also, dass die Darstellungsprobleme wirklich nur an meinem Computer lagen nehme ich an?

        Darstellungsprobleme bekommst du immer, wenn quasi der Schlüssel nicht zum kodierten Text passt. Die falsche Darstellung ist nur ein Folgefehler aufgrund nicht richtigen Dekodierens.

        Alles was du mit mysqldump hinbekommen kannst, steht in seiner Dokumentation. Hast du da mal nachgeschaut?
        Das habe ich schon vorher gelesen. Das einzige, was erfolgversprechend geklungen hat, war --result-file. Hat aber nichts geändert.

        Ich hab auch nichts gefunden.

        Kommt sicher false raus oder ist nur die letzte Zeile der Ausgabe eine Leerzeile, die auch als false erkannt wird? Ein typsicherer Vergleich mit === oder !== räumt Zweideutigkeiten aus dem Weg.
        Das verstehe ich leider nicht.

        Type comparison tables. Wenn Datentypen in einen boolschen Kontext gebracht werden, so werden einige Werte als false und der Rest als true gewertet. Ein Leerstring wäre false.

        "" == false

        Wenn man aber die Datentypen berücksichtigt, dass wird hier ein String mit einem Boolean vergleichen. Bei einem typsicheren Vergleich ist "" nicht mehr false

        "" !== false

        Wenn also system() einen Leerstring liefert, dann wird der als false gewertet, wenn nicht typsicher verglichen wird.

        Wenn ich var_dump(system("mysqldump...")) mache bekomme ich string(0) ""
        Bei var_dump() vom Output von system bekomme ich int(0)

        0 wäre auch false. Fehler werden in der Regel mit Werten ungleich 0 signalisiert.

        "" und 0 sind also beide == false aber !== false.

        Lo!

        1. Hi,

          Type comparison tables. Wenn Datentypen in einen boolschen Kontext gebracht werden, so werden einige Werte als false und der Rest als true gewertet. Ein Leerstring wäre false.

          "" == false

          Wenn man aber die Datentypen berücksichtigt, dass wird hier ein String mit einem Boolean vergleichen. Bei einem typsicheren Vergleich ist "" nicht mehr false

          "" !== false

          Wenn also system() einen Leerstring liefert, dann wird der als false gewertet, wenn nicht typsicher verglichen wird.

          Wenn ich var_dump(system("mysqldump...")) mache bekomme ich string(0) ""
          Bei var_dump() vom Output von system bekomme ich int(0)

          0 wäre auch false. Fehler werden in der Regel mit Werten ungleich 0 signalisiert.

          "" und 0 sind also beide == false aber !== false.

          So werde ich das dann machen. Das ist aber dann wohl nur der erste Schritt, also ob überhaupt etwas ausgeführt wurde, oder?

          Als nächstes habe ich mir gedacht, dass ich in der .sql Datei nach "-- Dump completed on" suchen kann. Das kommt ja glaube ich wirklich nur, wenn es geklappt hat.

          Wenn ich dann kein "-- Dump completed on" in der Datei finde, soll das System mir eine Fehlermeldung Mailen...

          Achja nochwas:
          ICh habe mal die -hex-blob Option ausprobiert. Jetzt sehen die Einträge in den BLOBS so aus wie bei dem Dump aus phpMyAdmin und die Umlaute sehen jetzt auch richtig aus. Wahrscheinlich sit diese Option wegen den PDFs in der BLOB spalte auch besser, oder?
          Aber funktioniert hat das Restore auch vorher...

          Gruß
          Alex

  2. Hallo,

    mir ist bei mysqldump noch etwas aufgefallen.

    Wenn ich über --lock-all-tables oder -x die ganzent abellen sperren alssen will klappt der Dump nicht.
    Das selbe passiert, wenn ich --debug anwenden will.

    Klappt nicht == es wird eine Datei mit der Größe 0 erzeugt.

    Woran kann das liegen? Mache ich da was falsch, oder kann es einfach sein, dass diese Funktionen deaktiviert sind?

    Gruß
    Alex

    1. Hi!

      Wenn ich über --lock-all-tables oder -x die ganzent abellen sperren alssen will klappt der Dump nicht.

      Keine Ahnung. Aber warum willst du das überhaupt machen? Gibt es dazu einen technischen Grund?

      Lo!

      1. Hi,

        Keine Ahnung. Aber warum willst du das überhaupt machen? Gibt es dazu einen technischen Grund?

        So wie ich das verstanden habe könnte sonst während dem Backup in eine andere Tabelle geschrieben werden und nur in der, die gerade gedumpt wird, liegt eine Sperre vor (wenn -l genutzt wird).

        Ich habe aber viele Abhängigkeiten zwischen den Tabellen. Es wäre also sehr schlecht, wenn nur die eine gefüllt wird und die andere nicht. Das wird zwar auch an den kritischen Stellen in den anderen Skripts überprüft, aber ich habe mir gedacht sicher ist sicher :)

        Gruß
        Alex

        1. Hi!

          Ich habe aber viele Abhängigkeiten zwischen den Tabellen. Es wäre also sehr schlecht, wenn nur die eine gefüllt wird und die andere nicht. Das wird zwar auch an den kritischen Stellen in den anderen Skripts überprüft, aber ich habe mir gedacht sicher ist sicher :)

          Dann musst du die Sperren beim Ändern anlegen. Beim Dumpen ist das witzlos, weil sie ja in einen komplexen Prozess hineinplatzen und den zweiteilen kann.

          Lo!

          1. Hi,

            Dann musst du die Sperren beim Ändern anlegen. Beim Dumpen ist das witzlos, weil sie ja in einen komplexen Prozess hineinplatzen und den zweiteilen kann.

            Klingt logisch.

            Also du meinst, dass es eher wahrscheinlich ist, dass die Sperre beim täglichen Dumpen einem solchen "abhängigen prozess" dazwischenfährt. Und dass es eher unwahrscheinlicher ist, dass ein Dump mit dann nichtmerh zusammen hängenden Daten widerhergestellt werden muss. Oder?

            Also verlasse ich mich ganz auf die Fehlerbehandlung beim Anlegen der Datensätze. Und wenn ich mal das Backip wirklich brauchen sollte, stelle ich die Seite in den Wartungsmodus, bevor ich den Restore mache...

            Gruß
            Alex

            1. Hi!

              Also verlasse ich mich ganz auf die Fehlerbehandlung beim Anlegen der Datensätze. Und wenn ich mal das Backip wirklich brauchen sollte, stelle ich die Seite in den Wartungsmodus, bevor ich den Restore mache...

              Du solltest bei solch kritischen Aktionen über Transaktionen nachdenken. Die garantieren, dass entweder alles oder nichts eingetragen wird.

              Lo!