Empfehlungen: Erweiterte Suche

Datenbanksicherung mit cake-Shell

Anleitungen und Quellcode-Auszüge die den Start vereinfachen sollen.

Datenbanksicherung mit cake-Shell

Beitragvon getit » So 21. Jun 2009, 15:24

Hier gibt es eine Thread http://www.cakephp-forum.com/post712.html?hilit=backup#p712 wo Probleme im Umgang mit dem Backup einer Datenbank beschrieben sind.

Dieses Probleme umgehe ich dadurch, dass ich das Backup nicht mit einem Controller sondern einer cakeShell erledige.
Diese Shell kann dann einfach durch zb. einen Cronjob aufgerufen werden.

Hier die Shell die alle Informationen zu den Tabellen ausliest.
Folgende Datei in /app/vendors/shells/db_dump.php erzeugen:
Code: Alles auswählen

<?php
class DbDumpShell extends Shell {
    var $tasks = array('WriteSql');
   
    /*
     * Main der Shell
     *  ruft nacheinander die Methoden zum Erzeugen der Tabellen und deren Inhalte auf
     *
     */

    function main() {
        App::import('Core', 'Configure');
        $this->Configure = new Configure();
        $models = $this->Configure->listObjects('model');
       
        foreach ($models as $model) {
            App::import('Model', $model);
            $this->$model = new $model();
        }
       
        $tables = array();     
        $tables = $this->getTables($models);
        $tablesTmp = $this->getFields($models);
        foreach ($tables as $key => $value) {
            $tables[$key]['contents'] = $tablesTmp[$key]['contents'];
        }
       
        $this->WriteSql->execute($tables);  //Aufruf des Tasks
    }
   
    /*
     * Liefert die sql-Statements zum Erstellen der Tabellen
     *
     * @param array $models: Array aller Models
     * @return array $tables: sql-Statement zum Erstellen der Tabellen
     */

    function getTables($models) {
        App::import('Core', 'Inflector');
       
        $tables = array();
        foreach ($models as $model) {
            $tableName = Inflector::tableize($model);
           
            if ($this->$model->useTable != '') {
                $sql = 'describe ' . $tableName;
                $columns = $this->$model->query($sql);
               
                $tables[$model]['table'] = 'create table ' . $tableName . '(';
                    $i = 0;
                    foreach ($columns as $column) {
                        $key = ($column['COLUMNS']['Key'] == 'PRI') ? 'primary key' : '';
                        if ($i == count($columns) - 1) {
                            $tables[$model]['table'] .= '`' . $column['COLUMNS']['Field'] . '` ' . $column['COLUMNS']['Type'] . ' ' . $column['COLUMNS']['Extra'] . ' ' . $key;
                        } else {
                            $tables[$model]['table'] .= '`' . $column['COLUMNS']['Field'] . '` ' . $column['COLUMNS']['Type'] . ' ' . $column['COLUMNS']['Extra'] . ' ' . $key . ', ';
                        }
                        $i++;
                    }
                $tables[$model]['table'] .= ') character set utf8 collate utf8_unicode_ci;';
            }
        }
       
        return $tables;
    }
   
    /*
     * Liefert die Inhalte aller Tabellen
     *
     * @param array $models: Array aller Tabellen
     * @return array $tables: Array mit den Inhalten der jeweiligen Tabelle
     */

    function getFields($models) {
        App::import('Core', 'Inflector');
       
        $tables = array();
        foreach ($models as $model) {
            $tableName = Inflector::tableize($model);

            if ($this->$model->useTable != '') {
                $contents = $this->$model->find('all');
                $i = 0;
                foreach ($contents as $content) {
                    $tables[$model]['contents'][$i] = 'INSERT INTO `' . $tableName . '` VALUES (';
                    $y = 0;
                    foreach ($content[$model] as $field) {
                        if ($y == 0) {
                            $tables[$model]['contents'][$i] .= '"' . $field . '"';
                        } else {
                            $tables[$model]['contents'][$i] .= ', "' . $field . '"';
                        }
                        $y++;
                    }
                    $tables[$model]['contents'][$i] .= ');';
                    $i++;
                }
            }
        }
       
        return $tables;
    }
}
?>
 


Und dieser Task übernimmt das Speichern der Daten.
Datei /app/vendors/shells/tasks/write_sql.php mit folgendem Inhalt erzeugen:
Code: Alles auswählen

<?php
class WriteSqlTask extends Shell {
    function execute($tables) {
        $today = getdate();
        App::import('Core', 'File');
        $file = new File(APP . DS . 'webroot' . DS . 'backups' . DS . 'dump_' . $today['mday'] . $today['month'] . $today['year'] . '.sql', true);
       
        App::import('Core', 'Inflector');
       
        foreach ($tables as $key => $value) {
            $tableName = Inflector::tableize($key);
           
            $file->write('#' . "\n" . '# Table ' . $tableName . "\n" . '#' . "\n");
            $file->write($value['table'] . "\n\n");
           
            foreach ($value['contents'] as $content) {
                $file->write($content . "\n");
            }
            $file->write("\n\n\n\n");
        }
        $file->close();
    }
}
?>
 


Jetzt einfach in die cake Console wechseln.
Und dort eingeben: cake db_dump


Unter /app/webroot/backups werden nun die Backups abgelegt.
getit
 
Beiträge: 105
Registriert: Mo 22. Dez 2008, 13:06
CakePHP-Version: 1.2.1.8004
OS: Vista

Re: Datenbanksicherung mit cake-Shell

Beitragvon euromark » Mo 22. Jun 2009, 11:28

habs grad mal ausprobiert
bei mir kommts zu nem Fatal Error:
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate
16 bytes) in F:\...\cake\libs\model\datasources\dbo\dbo_mysql
i.php on line 394

aufgrund der vielen Daten, die hier natürlich ausgelesen werden (und ich hab noch ne recht kleine DB)
euromark
 
Beiträge: 618
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.1
OS: Windows

Re: Datenbanksicherung mit cake-Shell

Beitragvon getit » Mo 22. Jun 2009, 11:47

Sehr komisch.

Da versucht man mal zu helfen und dann sowas :( .

Also bei mir läuft es ohne Probleme - sorry kann Dir leider nicht weiterhelfen.
getit
 
Beiträge: 105
Registriert: Mo 22. Dez 2008, 13:06
CakePHP-Version: 1.2.1.8004
OS: Vista

Re: Datenbanksicherung mit cake-Shell

Beitragvon euromark » Mo 22. Jun 2009, 12:47

das passiert bei Datenbank-Inhalten jenseits von mehreren hundert Zeilen

daher habe ich mit ressourcenschonenderen Verfahren wie dieser Shell (Auszug!)
Code: Alles auswählen
    function backupToFile($tableName = null, $override = true) {
        $backupFile = DB_BACKUP_DUMP_PATH.$tableName.'.sql'; // Inflector::underscore($tableName)
        if ($override &amp;&amp; file_exists($backupFile)) {
            unlink($backupFile);
        }
        $query      = "SELECT * INTO OUTFILE '$backupFile' FROM `$tableName`";
        $result = $this->Model->query($query);
        return $result;
    }

    function backupFromFile($tableName = null, $trancate = true) {
        $backupFile = DB_BACKUP_DUMP_PATH.$tableName.'.sql';
        $query      = "TRUNCATE TABLE `$tableName`";
        $result = $this->Model->query($query);
        $query      = "LOAD DATA INFILE '$backupFile' INTO TABLE `$tableName`";
        $result = $this->Model->query($query);
        return $result;    
    }
 

bessere Erfahrungen gemacht
euromark
 
Beiträge: 618
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.1
OS: Windows

Re: Datenbanksicherung mit cake-Shell

Beitragvon havanna » Mo 22. Jun 2009, 19:52

Hallo Mark,

wie wär's wenn du das mal als Tutorial/Snippet präsentierst? :)

Ciao Thomas
Benutzeravatar
havanna
 
Beiträge: 191
Registriert: Mi 15. Okt 2008, 23:12
Wohnort: Bodman-Ludwigshafen
CakePHP-Version: 1.2.x
OS: WIN

Re: Datenbanksicherung mit cake-Shell

Beitragvon euromark » Mo 22. Jun 2009, 20:31

meine shellskripte sind oft sehr windowslastig programmiert - also unter umständen laufen sie dann nich auf anderen systemen.
aber kann ich sicher mal machen :)
euromark
 
Beiträge: 618
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.1
OS: Windows


Zurück zu Tutorials und Snippets

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste

cron