Mysql
 sql >> Datenbank >  >> RDS >> Mysql

PDO-MySQL-Backup-Funktion

Dieses Backup-Skript ist lächerlich und niemand sollte eine andere Version davon erstellen. Ich habe dieses Skript sowie ähnliche Versuche schon einmal gesehen, und sie haben viele Probleme:

  • Trennt Tabellennamen nicht in Backticks
  • Verarbeitet keine NULLen
  • Bearbeitet keine Zeichensätze
  • Verarbeitet keine Binärdaten
  • Sichert keine VIEWS
  • Sichert keine TRIGGER oder GESPEICHERTEN PROZEDUREN oder GESPEICHERTEN FUNKTIONEN oder EREIGNISSE
  • Verwendet eine veraltete mysql-Erweiterung (aber das ist der Grund, warum Sie eine PDO-Version wollen, nicht wahr?)
  • Verwendet addedlashes() anstelle einer richtigen MySQL-Escape-Funktion.
  • Hängt alle an Daten für alle Tabellen in eine wirklich lange Zeichenfolge, bevor der gesamte Inhalt ausgegeben wird. Das bedeutet, dass Sie in der Lage sein müssen, Ihre gesamte Datenbank in einem String zu speichern, was mit ziemlicher Sicherheit Ihr maximales Speicherlimit für PHP sprengen wird.

Siehe auch meine letzte Antwort zum unglücklichen Backup-Skript von David Walsh:

Zu Ihrem Kommentar:

Lesen Sie die Kommentare auf der verlinkten Seite. Viele Leute haben Probleme identifiziert, und einige haben Korrekturen oder zumindest Vorschläge.

Die Tatsache, dass dieses Skript alles an eine Zeichenfolge anhängt, ist meiner Meinung nach ein Deal-Breaker, aber es sollte nicht schwierig sein, das Skript so zu ändern, dass die Ausgabedatei zuerst geöffnet wird , geben Sie dann die Daten jeder Zeile während der Schleife aus und schließen Sie die Datei nach der Schleife. Das ist irgendwie ein Kinderspiel, ich bin mir nicht sicher, warum das Skript das nicht tut. Aber es ist ziemlich klar, dass das Skript nicht sehr gut getestet wurde.

Aber trotzdem würde ich nicht versuchen, dieses Rad neu zu erfinden. Mysqldump oder mydumper erledigen diese Aufgabe gut. FWIW, Sie müssen mysqldump nicht auf demselben Server ausführen, auf dem sich die Datenbank befindet. Mysqldump unterstützt eine Option für --host Sie können also mysqldump überall ausführen, um eine entfernte Datenbank zu sichern, solange Firewalls Ihren Client nicht daran hindern, sich zu verbinden. Wenn Sie eine PHP-App von einem Client-Host aus mit der Datenbank verbinden können, können Sie grundsätzlich mysqldump verbinden.

Wenn das wirklich keine Option ist, dann würde ich die Datenbank-Dump-Funktion von phpmyadmin verwenden. Diese sind ausgereift und gut getestet und sie geben alles korrekt ab. Hier ist ein Artikel, der die Verwendung der Dump-Funktion beschreibt:

http://www.techrepublic. com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/

[Kopiere meine Kommentare aus deiner Antwort:]

Dies ist ein Einstieg in die Codeüberprüfung, was nicht der Zweck von StackOverflow ist. Aber kurz:

  • keine richtige Unterstützung für NULL (man konvertiert sie in '');
  • Tabellennamen nicht konsequent begrenzen;
  • Nicht-ANSI-Anführungszeichen als Zeichenkettenbegrenzer verwenden;
  • Die Verwendung von gepufferten Abfragen für riesige Tabellen wird die maximale Speichergrenze von PHP überschreiten;
  • das Anhängen aller Zeilen für eine riesige Tabelle wird das maximale Speicherlimit von PHP überschreiten;
  • Addlashes() anstelle von PDO::quote();
  • Suche nach Abfragefehlern nur am Ende der Funktion;
  • keine Überprüfung auf fehlgeschlagene Dateierstellung;
  • gzip-Erweiterung darf nicht geladen werden
  • Außerdem werden UTF8-Daten wahrscheinlich immer noch nicht unterstützt.

Ja, das ist besser als das ursprüngliche Drehbuch von David Walsh. :-)

NULL ist nicht dasselbe wie '' in SQL (außer in Oracle, aber sie entsprechen in diesem Fall nicht dem SQL-Standard). Siehe MySQL, besser NULL oder leer einfügen Zeichenkette?

Ich habe den Code zum Problem mit der Speicherbegrenzung falsch gelesen. Sie schreiben die Ausgabe für jede Zeile, das ist also in Ordnung (es sei denn, die Zeile enthält einen 1-GB-Blob oder so etwas).

Aber Sie sollten nicht einfach eine einzelne INSERT-Anweisung mit einer durch Kommas getrennten Reihe von Zeilen ausgeben. Sogar mysqldump --extended-insert gibt eine endliche Datenlänge aus und startet dann eine neue INSERT-Anweisung. Das Kriterium ist, ob die Länge der INSERT-Anweisung in das Optionsargument für --net-buffer-length passt .

In ANSI SQL werden einfache Anführungszeichen '' verwendet, um Zeichenfolgenliterale oder Datumsliterale zu begrenzen. Doppelte Anführungszeichen "" werden verwendet, um Bezeichner wie Tabellennamen oder Spaltennamen abzugrenzen. Standardmäßig behandelt MySQL sie gleich, aber das ist kein Standard. Siehe Verwenden unterschiedliche Datenbanken unterschiedliche Namenszitate? . Wenn Sie versuchen, Ihre Sicherungsdaten auf einen MySQL-Server zu importieren, auf dem Sie SET SQL_MODE=ANSI_QUOTES haben , schlägt der Import fehl.

Beispiel:query('SELECT * FROM '.$table); und tatsächlich jeder der anderen Fälle, in denen Sie $table in einer Abfrage verwenden. Sie haben die Tabelle nur einmal getrennt, in der INSERT-Anweisung, die Ihr Skript ausgibt.

MySQL erkennt Backticks immer als Trennzeichen für Bezeichner und einfache Anführungszeichen für Zeichenfolgen/Datumsangaben. Aber doppelte Anführungszeichen ändern ihre Bedeutung je nach dem von mir erwähnten SQL_MODE. Sie können nicht davon ausgehen, welcher SQL_MODE auf der MySQL-Instanz wirksam ist, auf der Sie wiederherstellen, daher ist es am besten, wenn Sie die Backticks für Bezeichner und einfache Anführungszeichen für Zeichenfolgen verwenden. Der Grund, warum Sie sie beim Abfragen Ihrer Tabelle abgrenzen würden, ist, dass Sie möglicherweise Tabellennamen haben, die SQL-reservierte Wörter sind oder Sonderzeichen usw. enthalten.

Sie können alle numerischen Typen ohne Trennzeichen einfügen. Nur Zeichenfolgen und Datumsangaben benötigen Trennzeichen. Siehe dev.mysql.com/doc/refman/5.6/en/literals.html