Mit Cronjob MySql DB backuppen

  • Hallo


    dieses Thema würde eigentlich in das Form "Conifxx und PHP|MySql" passen, jedoch handelt es sich auch um CGI, deswegen einfach hier rein, falls es gar nicht hier rein passt, bitte verschieben.


    Also, ich versuche mit einem Cronjob meine MySql DB zu backuppen.
    Dafür habe ich den Cronjob so eingestellt
    (Tesweise alle 5min)

    Code
    */5 * * * * /usr/bin/php5 /var/www/web143/html/cgi-bin/backup.php

    mein PHP Script sieht wie folgt aus:


    Testweise habe ich die php datei und den ordner backup mit den rechten 777 ausgestattet


    so, nachdem ich nun in Confixx bei dem Cronjob auf speichern gedrückt habe, habe ich mal so 10min gewartet und dann bekam ich eine e-Mail von Cron Daemon mit folgendem Inhalt:

    Die Datei backup.php habe ich in den cgi-bin Ordner gelegt, weil ich irgendwo mal gehört habe, dass ein Cronjob nur dort ausgeführt wird.


    Ich habe schon vieles versucht, auch mit CGI Scripten, jedoch bekam ich immer eine E-Mail (bei dem CGI-Script jedoch mit einer anderen Fehlermeldung).


    Ich weiß wirklich nicht mehr wo der Fehler liegt.
    Es wäre nett, wenn ihr mit helfen könntet.


    Noch eine Anmerkung, ich besitze das Produkt Business 1024.


    Mfg. Tobias

  • Hast du es schon einmal mit dem MySQL-Dumper versucht?
    Der ist für MySQL Backups auf einem Webspace eigentlich das Beste [1] :)



    MfG Christian



    [1] Außer man darf die PHP-Funktion exec() nutzen und mysqldump ausführen :D

    "Wer nur noch Enten sieht, hat die Kontrolle über seine Server verloren." (Netzentenfund)

  • jup, bei dem mysqldumper funktioniert das Backup per php auch gut, einbinden in einen Cronjob kann ich dies nicht, weil der dumper mit selbstaufrufen arbeitet.
    Das Backup per Perl funktioniert nicht, weil bei dem Produkt Business 1024 kein Perl vorhanden ist


    Mfg. Tobias


    edit:


    wie meinst du das mit dem [1]

  • Zitat

    wie meinst du das mit dem [1]


    Hättest du nen vServer, hättest du shell_exec() bzw. exec() erlauben können und einfach /usr/bin/mysqldump ausführen können.

    Mein Server:
    v(olks)Server 1. Serie: 2,5GHz, 1024MB RAM, 1024MB Swap, 2x60GB-Raid1-HDD, Traffic-Flat
    Node:
    78.46.117.9x | hos-tr2.ex3k4.rz7.hetzner.de

  • Wie genau sehen die Berechtigung der Datei, sowie der Ordner aus?


    Die Fehlermeldung Permission Denied deutet ja ziemlich eindeutig darauf hin dass die Datei nicht erstellt werden kann.

  • Zitat von Servior;14826

    Wie genau sehen die Berechtigung der Datei, sowie der Ordner aus?


    Die Fehlermeldung Permission Denied deutet ja ziemlich eindeutig darauf hin dass die Datei nicht erstellt werden kann.


    so:


    cgi-bin/ <--- 777
    cgi-bin/backup/ <--- 777
    cgi-bin/backup.php <--- 777

  • Ist cgi-bin der erste Ordner?


    Ggf. verhindert der Ordner darüber bereits den Schreibzugriff.
    Kannst du von Hand eine Datei in den Ordner hochladen, bzw. erstellen?

  • Zitat von Artimis;14817

    Hättest du nen vServer, hättest du shell_exec() bzw. exec() erlauben können und einfach /usr/bin/mysqldump ausführen können.


    Ich habs eigentlich nur deshalb erwähnt, weil man das bei diversen anderen Hostern kann. Habe ich selbst jahrelang so genutzt ;) :D



    MfG Christian

    "Wer nur noch Enten sieht, hat die Kontrolle über seine Server verloren." (Netzentenfund)

  • Zitat von Servior;14832

    Ist cgi-bin der erste Ordner?


    Ggf. verhindert der Ordner darüber bereits den Schreibzugriff.
    Kannst du von Hand eine Datei in den Ordner hochladen, bzw. erstellen?


    also wenn ich über die Domain auf den Webserver zugreife, dann komme ich sofort in das html verzeichniss, jedoch wenn ich per ftp zugreife, dann komme ich vor das html verzeichniss,
    ergo


    ftp /html/cgi-bin/
    domain /cgi-bin/


    ich gebe dem html ordner mal die rechte 777 mal schauen was passiert, einen moment bitte


    edit:


    also wenn ich dem ordner html die rechte 777 gebe, dann bekomme ich einen 500 Internal Server Error

  • 1. $speicherort als absoluten Pfad anlegen.
    2. Unlink vor fopen brauchst du nicht da fopen -w die Datei schon leert.
    3. Du musst die komplette Datenbank sperren während du die Sicherung machst. Sollte ein anderer Prozess in eine Tabelle schreiben ist es reiner Zufall ob du die Daten im Backup hast oder nicht. Stelle dir z.B. vor, ein CMS erstellt genau während der Sicherung eine neue Seite in zwei Tabellen. In der ersten Tabelle ist der Seiteninhalt, in der zweiten Metadaten. Nun ist deine Sicherung zu dem Zeitpunkt genau soweit, dass du an der Inhaltstabelle schon vorbei bist, aber die Metadaten noch in die Sicherung mit reinkommen. Da du jetzt inkonsistente Daten in deinem Backup hast wirst du es nicht wiederherstellen können.

  • also
    so


    zu 3. das mit dem sperren habe ich noch nie gehört, gibt es dafür einen php befehl? unter google abe ich leider nichts gefunden.


    edit:
    also nun funktioniert es :):):)


    das Script erstellt mir nun ein Backup in den Backup Ordner.
    nun fehlt mir nur noch das mit der Datenbank sperren

  • ich habs mal nun so gemacht
    stimmt das?


    [PHP]<?php


    /* Einstellungen start */
    $mysql_host = "localhost"; //MySQL-Hostname
    $mysql_dbs = array('DB_TABELLE');
    $mysql_user = "DB_USER"; //Mysql-Benutzer
    $mysql_pass = "DB_PW"; //Mysql-Passwort
    $speicherort = "/var/www/web143/html/cgi-bin/backup/"; //Speicherort
    /* Einstellungen ende */



    $mysql_link = @mysql_connect($mysql_host,$mysql_user,$mysql_pass);
    if($mysql_link == false)
    {
    die("-E: Verbindung zur Datenbank ist fehlgeschlagen!<br>\n");
    }
    /* Tabellen sperren start */
    $result = mysql_query("FLUSH TABLES WITH READ LOCK");
    if (!$result) {
    die('Ungültige Abfrage: ' . mysql_error());
    }
    $result = mysql_query("FLUSH LOGS");
    if (!$result) {
    die('Ungültige Abfrage: ' . mysql_error());
    }
    /* Tabellen sperren ende */
    if(!isset($mysql_dbs))
    {
    $mysql_db_list = mysql_list_dbs($mysql_link);
    if(mysql_num_rows($mysql_db_list) <= 0)
    {
    die("-E: Keine Datenbank(en) gefunden<br>\n");
    }
    while ($row = mysql_fetch_array($mysql_db_list))
    {
    $mysql_dbs[] = $row[0];
    }
    }
    foreach($mysql_dbs as $mysql_db)
    {
    mysql_select_db($mysql_db);
    $mysql_tables = array();
    $mysql_table_list = mysql_list_tables($mysql_db);
    if(mysql_num_rows($mysql_table_list) >= 1)
    {
    while ($row = mysql_fetch_row($mysql_table_list))
    {
    $mysql_tables[] = $row[0];
    }
    }
    $file = $speicherort.$mysql_db."-".date('d.m.Y').".sql";
    /*Hier war das mit dem Unlink($file); */
    $backup = fopen($file,'w');
    foreach($mysql_tables as $mysql_table)
    {
    $mysql_table_info = Array();
    $i = 0;
    $mysql_table_infos = mysql_query("DESCRIBE ".$mysql_table);
    while($row = mysql_fetch_array($mysql_table_infos))
    {
    $mysql_table_info[$i]['fieldname'] = $row[0];
    $mysql_table_info[$i]['typ'] = $row[1];
    $mysql_table_info[$i]['null'] = $row[2];
    $mysql_table_info[$i]['key'] = $row[3];
    $mysql_table_info[$i]['default'] = $row[4];
    $mysql_table_info[$i]['extra'] = $row[5];
    $i++;
    }
    $befehl = "CREATE TABLE IF NOT EXISTS `".$mysql_table."` (\n";
    $pri = false;
    $auto_increment = false;
    $increment_feld = "";
    fwrite($backup,"-- --------------------------------------------------\n-- Struktur der Tabelle ".$mysql_table."\n-- --------------------------------------------------\n\n");
    foreach($mysql_table_info as $mysql_spalte_info)
    {
    $befehl .= " `".$mysql_spalte_info['fieldname']."` ";
    $befehl .= $mysql_spalte_info['typ']." ";
    if($mysql_spalte_info['default'] != "")
    $befehl .= "default `".$mysql_spalte_info['default']."` ";
    else
    $befehl .= "default NULL";
    if($mysql_spalte_info['extra'] != "" || !empty($mysql_spalte_info['extra']))
    $befehl .= " ".$mysql_spalte_info['extra'].",\n";
    else
    $befehl .= ",\n";
    if($mysq_spalte_info['key'] != "" || !empty($mysql_spalte_info['key']))
    {
    $pri[] = $mysql_spalte_info['fieldname'];
    }
    if($mysql_spalte_info['extra'] != "" || !empty($mysql_spalte_info['extra']))
    {
    $auto_increment = true;
    $increment_feld = $mysql_spalte_info['fieldname'];
    }
    }
    $befehl = substr($befehl,0,(strlen($befehl)-2));
    if($pri != false)
    {
    $befehl .= ",\n PRIMARY KEY (";
    foreach($pri as $pr)
    $befehl .= "`".$pr."`,";
    $befehl = substr($befehl,0,(strlen($befehl)-1));
    $befehl .= ")";
    }
    if($auto_increment)
    {
    $auto_inc = mysql_query("SELECT ".$increment_feld." FROM ".$mysql_table." ORDER BY ".$increment_feld." DESC LIMIT 1");
    while($inc = mysql_fetch_assoc($auto_inc))
    {
    $zahl = $inc[$increment_feld]+1;
    }
    $befehl .= "\n) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=".$zahl." ;\n\n";
    }
    else
    {
    $befehl .= "\n) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;\n\n";
    }
    fwrite($backup,$befehl);
    fwrite($backup,"-- --------------------------------------------------\n-- Daten der Tabelle ".$mysql_table."\n-- --------------------------------------------------\n\n");
    $befehl = "TRUNCATE TABLE `".$mysql_table."`;\n";
    fwrite($backup,$befehl);
    $datensaetze = mysql_query("SELECT * FROM ".$mysql_table.";");
    while ($datensatz = mysql_fetch_assoc($datensaetze))
    {
    $values = "";
    foreach($datensatz as $value)
    {
    $values .= "'".mysql_real_escape_string($value)."',";
    }
    $values = substr($values,0,(strlen($values)-1));
    $befehl = "INSERT INTO `".$mysql_table."` VALUES (".$values.");\n";
    fwrite($backup,$befehl);
    }
    }
    echo "Backup of ".$mysql_db." done<br>\n";
    fclose($backup);
    }
    /* Tabellen ENTsperren start */
    $result = mysql_query("UNLOCK TABLES");
    if (!$result) {
    die('Ungültige Abfrage: ' . mysql_error());
    }
    /* Tabellen ENTsperren ende */
    mysql_close($mysql_link);
    ?> [/PHP]