Jak powielić bazę danych MySQL na tym samym serwerze

Mam dużą bazę danych MySQL, nazwijmy ją live_db, którą chcę replikować na tej samej maszynie, aby zapewnić system testowy do zabawy (test_db), w tym strukturę tabeli i dane. W regularnych odstępach czasu chcę zaktualizować {[1] } z zawartością live_db; jeśli to możliwe przyrostowe.

Czy Jest jakiś wbudowany mechanizm w MySQL do tego celu? Myślę, że replikacja master-slave nie jest rzeczą, której chcę, ponieważ powinno być możliwe modyfikowanie danych w test_db. Zmiany te nie muszą być jednak konserwowane.

Pozdrawiam,

CGD

Author: Avada Kedavra, 2011-07-11

4 answers

Klient linii poleceń mysql będzie akceptował strumień poleceń SQL ze standardowego wejścia. W związku z tym można przekierować wyjście mysqldump bezpośrednio do mysql w wierszu poleceń. Wykonując to zadanie cron, regularnie nadpisuje Twoje dane testowe zaktualizowanymi danymi na żywo:

mysql --user=username --password=passwd -e 'DROP DATABASE test_db;'
mysql --user=username --password=passwd -e 'CREATE DATABASE test_db;'
mysqldump --user=username --password=passwd live_db | mysql --user=username --password=passwd test_db

Zauważ, że ponieważ Twoje dane są duże, zajmie to dużo czasu.

 70
Author: Michael Berkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-15 11:05:56

Michaels answer abowe działa dobrze, ale nie kopiuje zdarzeń, procedur składowanych ani wyzwalaczy.

Aby je skopiować, potrzeba jeszcze kilku przełączników dla mysqldump: --events --triggers --routines

Aby uzupełnić już wykonaną kopię:

mysqldump --user=username --password=passwd --no-data --no-create-info --no-create-db --events --triggers --routines live_db | mysql --user=username --password=passwd test_db

 6
Author: Samuel Åslund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-20 10:15:38

Jeśli preferujesz Zestaw Narzędzi do migracji MySQL, możesz dwukrotnie kliknąć nazwę schematu w kroku mapowania danych i zmienić nazwę schematu docelowego.

 0
Author: Vasili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-09 18:12:14

To rozwiązanie działa dobrze, ale nie zadziała, jeśli używasz PHPunit do testów jednostkowych.

Użycie hasła w wierszu poleceń generuje ostrzeżenie, które jest przechwytywane przez PHPUnit i generuje wyjątek (tak, całkiem spora sprawa...)

Sposobem obejścia tego problemu jest użycie pliku konfiguracyjnego.

W moim przypadku nie chcę utrzymywać hasła i użytkownika zarówno w plikach konfiguracyjnych, jak i w kodzie PHP, więc generuję plik konfiguracyjny z kodu i sprawdzam, czy istnieje (w przeciwnym razie używam nazwy użytkownika i hasła bezpośrednio w wierszu poleceń jako opcji awaryjnej).

Oto przykład, w PHP, jak skopiować bazę danych konfiguracji, aby utworzyć nową o innej nazwie (jeśli na przykład zarządzasz domeną główną z inną subdomeną/bazą danych dla każdego klienta):

/**
* If the $dbName doesn't exist, then create it.
* 
* @param $errorMessage String to return the error message.
* @param $dbName String name of the database to create.
* @param $cleanExisting Boolean if the database exist, clear it to recreate it.
*
* @return boolean ($dbExists)
*/
private function createDatabase(&$errorMessage, $dbName, $clearExisting = false){

    $command = "";
    $configurationString = "[client]" . "\r\n" . "user=" . parent::$support_user . "\r\n" . "password=" . md5(parent::$support_pass);
    $dbExist = false;
    $path = realpath(dirname(__FILE__));

    $connectionString = " --defaults-extra-file=" . $path . "\mysql.cnf ";

    $dbName = strtolower($dbName);

    if ($this->isDestinationDbNameValid($errorMessage, $dbName)) {

        $dbExist = $this->isDestinationDbExist($errorMessage, $dbName);

        if (empty($errorMessage) and ($dbExist === false or $clearExisting === true)) {

            if (file_put_contents($path . '/mysql.cnf', $configurationString) === false) {

                $connectionString = " --user=" . parent::$support_user . " --password=" . md5(parent::$support_pass). " ";
            }

            if ($dbExist and $clearExisting) {

                $command = $path . '/../../../mysql/bin/mysql ' . $connectionString . ' --execute="DROP DATABASE ' . $dbName  .';" &';
            }

            $command .= '"' . $path . '/../../../mysql/bin/mysql" ' . $connectionString . ' --execute="CREATE DATABASE ' . $dbName . ';" &"' .
                        $path . '/../../../mysql/bin/mysqldump" ' . $connectionString . ' --events --triggers --routines setup | "' .
                        $path . '/../../../mysql/bin/mysql" ' . $connectionString . $dbName;

            exec($command);

            $dbExist = $this->isDestinationDbExist($errorMessage, $dbName);

            if (!$dbExist) {

                $errorMessage = parent::getErrorMessage("COPY_SETUP_DB_ERR", "An error occurred during the duplication process of the setup database.");
            }
        }
    }

    return $dbExist;
}

Uwaga dodatkowa:

  1. Musiałem użyć podwójnego cudzysłowu (") zamiast pojedynczego cudzysłowu ( " ) wokół moich poleceń SQL.

  2. Musiałem użyć ampersand ( & ) to separate my different command.

  3. Ten przykład nie zawiera walidacji nowej nazwy bazy danych (metoda isDestinationDbNameValid ()). Nie trzeba wspominać, że nigdy nie należy ufać wkładowi użytkownika...

  4. Musisz również napisać własną metodę, aby potwierdzić, że kopia bazy danych działała zgodnie z oczekiwaniami (metoda isDestinationDbExist ()). Powinieneś przynajmniej sprawdzić, czy istnieje baza danych, czy istnieje tabela z twojej konfiguracji i opcjonalnie, sprawdzanie poprawności zapisanych programów.

Użyj mocy mądrze moi przyjaciele,

Jonathan Parent-Lévesque z Montrealu]}
 -1
Author: Jonathan Parent Lévesque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-20 19:07:40