예제 #1
0
 public function init($myrole, $drivers)
 {
     $ret = parent::init($myrole, $drivers);
     if (true === $ret) {
         $this->_out->logNotice("generating simulated file system");
         // TODO prepare files needed for simulation if not already created
     }
     return $ret;
 }
예제 #2
0
 /**
  * @param Core_Engine  $engine
  * @param Output_Stack $output
  * @param array        $options
  *
  * @return \Storage_Filesystem
  */
 public function __construct($identity, $engine, $output, $options)
 {
     // filesystem options
     parent::__construct($identity, $engine, $output, $options);
     // test options
     if (!array_key_exists('storage', $this->_options)) {
         $this->_out->stop("parameter 'storage' is required by driver '{$this->_identity}'");
     }
     if (!in_array($this->_options['ifexists'], array('exit', 'use'))) {
         // TODO recreate - drop and create, keep - use and don't drop in the end
         $this->_out->stop("invalid value of parameter 'ifexists' detected by driver '{$this->_identity}'");
     }
     if (!isset($this->_options['key'], $this->_options['key']['access'])) {
         throw new Core_StopException("You have to define Amazon RDS option key.access.", "MysqlAmazonRdsInit");
     }
     if (!isset($this->_options['key']['secret'])) {
         throw new Core_StopException("You have to define Amazon RDS option key.secret.", "MysqlAmazonRdsInit");
     }
     // check if we know the mysql storage
     $this->_mysql = $this->_engine->getStorage($this->_options['storage']);
     $this->setBaseDir($this->_mysql->getBaseDir());
 }
예제 #3
0
    public function init($myrole, $drivers)
    {
        parent::init($myrole, $drivers);
        // make sure we are not restoring
        if ($myrole === Core_Engine::ROLE_REMOTE) {
            // TODO implement restore
            $this->_out->stop("MySql restore is not supported yet.");
        }
        // connect to mysql
        $this->_db = new PDO("mysql:host=" . $this->_options['host'] . ";port=" . $this->_options['port'] . ";dbname=mysql", $this->_options['user'], $this->_options['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
        // let PDO throw exception on errors
        $this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        // because of data amount we shouldn't use buffered queries
        $this->_db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
        $this->_driver = $this->_getBackupDriver();
        // build list of databases to backup
        $dbname = $this->_options['dbname'];
        $dbsToBackup = array();
        if (is_string($dbname)) {
            if ($dbname == '*') {
                // all dbs
                $this->_out->logNotice("retrieving names of all DBs from MySql server");
                $dbname = $this->_sqlToDbNames("SELECT schema_name as dbname FROM `information_schema`.`schemata` WHERE schema_name not in ('information_schema')");
            } elseif ($dbname[0] == '/') {
                // SQL
                $this->_out->logNotice("retrieving DB names based on provided SQL from MySql server");
                $dbname = $this->_sqlToDbNames(substr($dbname, 1));
            } else {
                // dbname only
                $dbsToBackup = array($dbname => array('dbname' => $dbname, 'addtobasedir' => $this->_options['addtobasedir']));
            }
        }
        if (is_array($dbname)) {
            // array or SQL was provided
            foreach ($dbname as $k => &$v) {
                if (is_array($v)) {
                    if (!array_key_exists('dbname', $v)) {
                        $v['dbname'] = $k;
                    }
                } else {
                    $v = array('dbname' => $v, 'addtobasedir' => $v);
                }
            }
            $dbsToBackup = $dbname;
        }
        // fix missing defaults
        $checkGzip = true;
        foreach ($dbsToBackup as $dbname => &$dbConfig) {
            if (!array_key_exists('dbname', $dbConfig)) {
                $dbConfig['dbname'] = $dbname;
            }
            if (!array_key_exists('compressdata', $dbConfig)) {
                if ($checkGzip && $this->_options['compressdata'] === "gzip") {
                    system("which gzip 2>&1 > /dev/null", $exitVal);
                    if (0 !== $exitVal) {
                        $this->_out->stop("External tool 'gzip' not found on this system.");
                    }
                    $checkGzip = false;
                }
                $dbConfig['compressdata'] = $this->_options['compressdata'];
            }
            if (!array_key_exists('addtobasedir', $dbConfig)) {
                $dbConfig['addtobasedir'] = $dbConfig['dbname'];
            }
            if (!array_key_exists('rotate', $dbConfig)) {
                $dbConfig['rotate'] = $this->_options['rotate'];
            } else {
                $dbConfig['rotate'] = array_merge($this->_options['rotate'], $dbConfig['rotate']);
            }
            if (!array_key_exists('filter-ext', $dbConfig)) {
                $dbConfig['filter-ext'] = $this->_options['filter-ext'];
            }
            if (!array_key_exists('with-passwords', $dbConfig)) {
                $dbConfig['with-passwords'] = $this->_options['with-passwords'];
            }
            if (!array_key_exists('server-location', $dbConfig)) {
                $dbConfig['server-location'] = $this->_options['server-location'];
            }
            if (!array_key_exists('no-data', $dbConfig)) {
                $dbConfig['no-data'] = $this->_options['no-data'];
            }
        }
        // backup database(s)
        $originalBaseDir = $this->_baseDir;
        unset($dbConfig);
        foreach ($dbsToBackup as $dbConfig) {
            $this->_baseDir = $originalBaseDir;
            $this->_driver->setDatabaseToBackup($dbConfig['dbname']);
            $this->_driver->setDataCompression($dbConfig['compressdata']);
            $this->_driver->setFilterExt($dbConfig['filter-ext']);
            $this->_driver->setWithPasswords($dbConfig['with-passwords']);
            $this->_driver->setServerLocation($dbConfig['server-location']);
            $this->_driver->setNoData($dbConfig['no-data']);
            $createForced = false;
            if ($dbConfig['addtobasedir']) {
                $this->_baseDir .= $dbConfig['addtobasedir'] . DIRECTORY_SEPARATOR;
                if (!file_exists($this->_baseDir)) {
                    @mkdir($this->_baseDir);
                    $createForced = true;
                }
            }
            $doRotate = $dbConfig['rotate']['days'] + $dbConfig['rotate']['weeks'] + $dbConfig['rotate']['months'] > 0;
            if ($doRotate) {
                $doRotate = $this->_baseDir;
                $this->_baseDir .= date("Y-m-d") . DIRECTORY_SEPARATOR;
                if (!file_exists($this->_baseDir)) {
                    @mkdir($this->_baseDir);
                    $createForced = true;
                }
            }
            // check/clear target folder
            if (!$createForced && file_exists($this->_baseDir)) {
                if ($doRotate) {
                    // the folder contains valid backup so we are going only to rotate
                    $this->_out->logWarning("backup folder '{$this->_baseDir}' already exists, skipping");
                    $this->_doRotation($doRotate, $dbConfig);
                    continue;
                } else {
                    // TODO check if it is empty and if we are allowed to delete it if not  && file_exists($this->_baseDir.'db/_name')
                    $this->_out->logWarning("removing existing content from backup folder '{$this->_baseDir}'");
                    $this->_clearFolder($this->_baseDir);
                }
            }
            // prepare debug file if needed
            if (isset($this->_options['_debugFolder']) && $this->_options['_debugFolder']) {
                // undocumented config option
                $this->_debugFolder = $this->_baseDir . DIRECTORY_SEPARATOR . "debug" . DIRECTORY_SEPARATOR;
            }
            if ($this->_debugFolder) {
                $this->_clearFolder($this->_debugFolder);
                @mkdir($this->_debugFolder);
                $f = fopen($this->_debugFolder . "1.sql", "w");
                fputs($f, <<<SQL
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
SQL
);
                fclose($f);
            }
            // retrieve all objects known in DB
            $this->_driver->listAvailableObjectsToBackup();
            $this->_driver->applyFilterToObjects();
            // execute backup of DB objects
            $host = $this->_options['host'];
            $msg = "creating backup of DB '{$dbConfig['dbname']}@{$host}' to folder '{$this->_baseDir}'";
            if ($dbConfig['compressdata']) {
                $msg .= ", data will be online compressed";
            }
            $this->_out->logNotice($msg);
            $this->_driver->doBackup($this);
            $this->_out->logNotice("adding restore script");
            $this->_driver->addRestoreScript($this->_baseDir);
            if (false !== $doRotate) {
                $this->_doRotation($doRotate, $dbConfig);
            }
        }
        $this->_baseDir = $originalBaseDir;
        $this->_out->logNotice("mysql backup finished");
        $this->_out->logNotice("high compression: 7za a -t7z -mmem=512m -m0=PPMd ../file.7z " . $this->_baseDir . "*");
        return true;
    }