Datenbank-Sicherung per php-Script

Thema wurde von barbara, 30. April 2016 erstellt.

  1. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    Hallo zusammen,

    ich habe mal eine Frage an die PHP-Profis:
    gibt es eine Möglichkeit eine Datenbank vernünftig per PHP-Script und Cronjob zu sichern?
    Ich habe zwar ein Script
    (Link nur für registrierte Nutzer sichtbar.)
    das hat aber zwei Nachteile:
    - es komprimiert nicht, dadurch ist eine Sicherung etwa 10x so groß wie mit dem MSD
    - es hat einen festgelegten Namen und überschreibt sich somit bei jeder Sicherung.

    Wenn ich jetzt die DB stündlich sichere und einen Fehler erst nach einer Stunde feststelle, muss ich auf eine viel ältere Sicherung zurückgreifen.

    Jetzt werden sich einige fragen "wieso ein Extra-Script, wenn der MSD installiert ist"
    Ganz einfach: auf dem Server ist Pearl / CGI gesperrt, ebenso wie system und exec.

    Freue mich auf hilfreiche Antworten :D
     
  2. Wilken (Gambio)

    Wilken (Gambio) Erfahrener Benutzer

    Registriert seit:
    7. November 2012
    Beiträge:
    18.737
    Danke erhalten:
    7.309
    Danke vergeben:
    2.208
    Das mit dem Datum/Zeit ist nicht so schwer, der Pfad zum Backup steht ja in einer Variablen. Du musst nur einen Teil des Dateinamens mit dem Ergebnis einer Zeitabfrage bestücken, zB so:

    Code:
    $datum=date(tmj);
    $ziel="backup-".$datum.".sql";
    Achte auf das Format von date, siehe hier:
    http://php.net/manual/de/function.date.php

    Komprimieren ginge auch. Zippen geht auch aus PHP heraus, das hat ne eigene Extension und damit Kommandos dafür, wenn der Hoster die nicht auch sperrt.

    Zum einlesen:
    http://php.net/manual/de/zip.examples.php
     
  3. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    http://www.gambio.de/forum/threads/datenbank-backup.20564/#post-168429
     
  4. Kai Schoelzke

    Kai Schoelzke Beta-Held

    Registriert seit:
    30. März 2016
    Beiträge:
    3.804
    Danke erhalten:
    548
    Danke vergeben:
    248
    Schau mal bei all-inkl, da gibt es eine Anleitung und ein Script
     
  5. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    Hallo Wilken,
    danke werde ich mir nachher einmal ansehen.

    Hallo Avenger,
    ich habe Dein Script gesehen, da sind aber exec-codes drinnen und die werden nicht ausgeführt.

    Hallo Kai,
    bei All inkl sind die Scripte leider auch mit exec, das funktioniert nicht.
     
  6. Kai Stejuhn

    Kai Stejuhn Beta-Held

    Registriert seit:
    26. September 2014
    Beiträge:
    1.409
    Danke erhalten:
    709
    Danke vergeben:
    92
    Hallo Barbara,

    ich habe das Script von oben mal erweitert (Textausgabe welche Tabellen gesichert wurden und ZIP). Bei mir auf dem Testserver lief das Script einwandfrei, kannst es ja mal ausprobieren.

    PHP:
    <?php
    $dbhost     
    "localhost";
    $dbuser     "BENUTZER";
    $dbpwd      "PASSWORT";
    $dbname     "DATENBANK";
    $dbbackup   "/absoluter/pfad/zum/erstellen/vom/backup.sql";
    $filename "/absoluter/pfad/zum/erstellen/vom/backup-$suffix.zip";

    // ab hier nichts mehr ändern
    $suffix time();
    echo 
    "Start des Backups<br>";
    error_reporting(0);
    set_time_limit(0);
    $conn mysql_connect($dbhost$dbuser$dbpwd) or die(mysql_error());
    mysql_select_db($dbname);
    $f fopen($dbbackup"w");
    $tables mysql_list_tables($dbname);
    while (
    $cells mysql_fetch_array($tables))
    {
        
    $table $cells[0];
        
    fwrite($f,"DROP TABLE `".$table."`;\n");
        
    $res mysql_query("SHOW CREATE TABLE `".$table."`");
        if (
    $res)
        {
            
    $create mysql_fetch_array($res);
            
    $create[1] .= ";";
            
    $line str_replace("\n"""$create[1]);
            
    fwrite($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);
                
    fwrite($f$line.");\n");
            }
            echo 
    "Tabelle: ".$table." wurde gesichert.<br>";
        }
    }
    fclose($f);
    #Now zip that file
      
    $zip = new ZipArchive();
      if (
    $zip->open($filenameZIPARCHIVE::CREATE) !== TRUE) {
       exit(
    "cannot open <$filename>n");
      }
      
    $zip->addFile($dbbackup $dbname.".sql");
      
    $zip->close();
      
    #Now delete the .sql file without any warning
      
    @unlink($dbbackup);
      
    #Return the path to the zip backup file
      
    echo "Backup ".$filename." wurde beendet.";
        
      return 
    $filename;
    ?>
    Der Dateiname wird mit einem Zeitstempel versehen, so dass immer eine neue Date erstellt wird.

    Hinweis: Benutzung auf eigene Gefahr, da nur auf einen lokalen Testserver ausprobiert.
     
  7. @barbara Gibt es bei All Inkl keine Möglichkeit per Knopfdruck gesamte Backups zu erstellen ? Bei mir sieht es so aus
    backup.jpg

    Oder geht es rein nur um die Datenbank ?

    Dann mach es doch mit dem MySQL Dumper

    Gruß Michael
     
  8. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    @kaistejuhn,

    Danke, werde ich ausprobieren und bereichten.

    @michael_76
    Es geht nicht um All inkl, da wären die Scripte von Avenger oder All inkl selbst ja nutzbar.
    Und der MySQLDumper geht nicht , da kein Pearl / CGI unterstützt wird.

    Deshalb ja meine Frage.
    Ein Vollbackup aller Dateien und Datenbanken könnte ich machen - einmal am Tag - das ist aber blöd, wenn man viel ändert und viele Kunden am Tag hat.
     
  9. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    Hallo @kaistejuhn,
    Das funktioniert leider auch nicht richtig.
    Jetzt wird es zwar als zip gepackt, aber da ist keine Zeitstempel im Dateinamen oder Datenbanknamen.
     
  10. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    So, ich habe es jetzt so hinbekommen, das ein Zip-Ordner erstellt wird und darin die Sicherungen mit Zeit.

    Lieben Dank an die Helfer :D
     
  11. Wilken (Gambio)

    Wilken (Gambio) Erfahrener Benutzer

    Registriert seit:
    7. November 2012
    Beiträge:
    18.737
    Danke erhalten:
    7.309
    Danke vergeben:
    2.208
    Fein. Achte nur darauf was passiert wenn die Shops in das PHP-Zeitlimit laufen, da liegt das Risiko. PHP ist bei solchen Aktionen wie hier vergleichsweise lahm und die Aktionen, die du hier wegen Sperrung umschiffen willst, sind meist genau bei den Hostern deaktiviert, die auch niedrige Zeitlimits haben...
     
  12. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    Ich hoffe mal das Estugo das kann. :)
     
  13. Torben Wark

    Torben Wark Gambio GmbH

    Registriert seit:
    15. Juli 2014
    Beiträge:
    2.581
    Danke erhalten:
    1.178
    Danke vergeben:
    399
    Damit das Ganze dann auch in Zukunft noch nutzbar ist, sollte das Script so angepasst werden, dass nicht die veralteten mysql_-Funktionen verwendet werden, sondern PDO oder mysqli. Sonst läuft das Script mit PHP7 nicht mehr.
     
  14. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    Hallo Torben,

    und wie mache ich das?
    Es wird ja wohl nicht reichen "mysql" in "mysqli" umzunennen, oder?
     
  15. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    19. August 2012
    Beiträge:
    195
    Danke erhalten:
    51
    Danke vergeben:
    19
    Hallo Barbara,

    das könnte Dir weiterhelfen.

    (Link nur für registrierte Nutzer sichtbar.)
     
  16. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    Hallo Berthold,

    werde ich testen :)
    Danke
     
  17. Torben Wark

    Torben Wark Gambio GmbH

    Registriert seit:
    15. Juli 2014
    Beiträge:
    2.581
    Danke erhalten:
    1.178
    Danke vergeben:
    399
    Das hier könnte funktionieren, ist aber nicht getestet:

    PHP:
    <?php

    $dbhost   
    "localhost";
    $dbuser   "BENUTZER";
    $dbpwd    "PASSWORT";
    $dbname   "DATENBANK";
    $dbbackup "/absoluter/pfad/zum/erstellen/vom/backup.sql";
    $filename "/absoluter/pfad/zum/erstellen/vom/backup-$suffix.zip";

    // ab hier nichts mehr ändern
    $suffix time();
    echo 
    "Start des Backups<br>";
    error_reporting(0);
    set_time_limit(0);
    $conn mysqli_connect($dbhost$dbuser$dbpwd) or die(mysqli_error($conn));
    mysqli_select_db($conn$dbname);
    $f      fopen($dbbackup"w");
    $tables mysqli_query($conn"SHOW TABLES FROM "$dbname);
    while(
    $cells mysqli_fetch_array($tables))
    {
        
    $table $cells[0];
        
    fwrite($f"DROP TABLE `" $table "`;\n");
        
    $res mysqli_query($conn"SHOW CREATE TABLE `" $table "`");
        if(
    $res)
        {
            
    $create mysqli_fetch_array($res);
            
    $create[1] .= ";";
            
    $line str_replace("\n"""$create[1]);
            
    fwrite($f$line "\n");
            
    $data mysqli_query($conn"SELECT * FROM `" $table "`");
            
    $num  mysqli_num_fields($data);
            while(
    $row mysqli_fetch_array($data))
            {
                
    $line "INSERT INTO `" $table "` VALUES(";
                for(
    $i 1$i <= $num$i++)
                {
                    
    $line .= "'" mysqli_real_escape_string($conn$row[$i 1]) . "', ";
                }
                
    $line substr($line0, -2);
                
    fwrite($f$line ");\n");
            }
            echo 
    "Tabelle: " $table " wurde gesichert.<br>";
        }
    }
    fclose($f);
    #Now zip that file
    $zip = new ZipArchive();
    if(
    $zip->open($filenameZIPARCHIVE::CREATE) !== true)
    {
        exit(
    "cannot open <$filename>n");
    }
    $zip->addFile($dbbackup$dbname ".sql");
    $zip->close();
    #Now delete the .sql file without any warning
    @unlink($dbbackup);
    #Return the path to the zip backup file
    echo "Backup " $filename " wurde beendet.";

    return 
    $filename;
     
  18. barbara

    barbara G-WARD 2014-2020

    Registriert seit:
    14. August 2011
    Beiträge:
    35.352
    Danke erhalten:
    11.198
    Danke vergeben:
    1.601
    Danke Torben,
    werde ich testen :)
     
  19. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    1. September 2012
    Beiträge:
    2.443
    Danke erhalten:
    421
    Danke vergeben:
    158
    #19 Anonymous, 27. November 2018
    Zuletzt bearbeitet: 27. November 2018
    Hallo Forum,

    gibt es da ein aktuelleres Script?
    Wir sind bei Estugo und möchten die DB sichern über Cronjob.
    Ich habe im root ganz oben einen Ordner angelegt namens "Backups"
    Darin eine DBbackup.php
    Diese mit Torbens Script bestückt, samt den DB Daten und den Pfaden:
    "$dbbackup = "backup.sql";
    "$filename = "backup-$suffix.zip";

    Eigentlich dachte ich das der Pfad leer bleibt und somit die Datei im selben Ordner wie der Aufruf gesichert wird. Kommt aber nichts, der Ordner bleibt leer.

    Beim Testaufruf des Scriptes in Estugo läuft es schön durch und wird mit "Die Aufgabe "/Backups/DBbackup.php" wurde erfolgreich in 6 Sekunden abgeschlossen. Aber wo sind die Backups?

    Hmmm.

    Edit: Backup gefunden, war noch höher im root, man muss doch den Pfad angeben...
    Aber der Dateiname enthält nicht den Zeitstempel. $suffix wird nicht übergeben....

    Gruß
     
  20. Kai Stejuhn

    Kai Stejuhn Beta-Held

    Registriert seit:
    26. September 2014
    Beiträge:
    1.409
    Danke erhalten:
    709
    Danke vergeben:
    92
    Setze mal

    PHP:
    $suffix time();
    direkt über

    PHP:
    $filename "/absoluter/pfad/zum/erstellen/vom/backup-$suffix.zip";