Подтвердить что ты не робот

Как дублировать базу данных MySQL на одном сервере

У меня есть большая база данных MySQL, давайте назовем ее live_db, которую я хочу реплицировать на том же компьютере, чтобы предоставить тестовую систему для воспроизведения (test_db), включая структуру и данные таблицы. Через регулярные промежутки времени я хочу обновить test_db с содержимым live_db; если возможно инкрементный.

Есть ли встроенный механизм в MySQL для этого? Я думаю, что репликация master-slave - это не то, что я хочу, так как можно было бы изменять данные в test_db. Однако эти изменения не должны сохраняться.

Привет,

КГД

4b9b3361

Ответ 1

Клиент командной строки mysql принимает поток SQL-запросов со стандартного ввода. Поэтому вы можете передать вывод mysqldump непосредственно в mysql в командной строке. Выполнение этого задания cron будет регулярно перезаписывать ваши тестовые данные с обновленными текущими данными:

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

Обратите внимание, что поскольку ваши данные большие, это займет много времени.

Ответ 2

Ответы Michaels abowe хорошо работают, но не копируют события, хранимые процедуры или триггеры.

Чтобы скопировать их, необходимо еще несколько переключателей для mysqldump: --events --triggers --routines

В дополнение к уже сделанной копии:

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

Ответ 3

Если вы предпочитаете MySQL Migration Toolkit, вы можете дважды щелкнуть по имени схемы на шаге Data Mapping и изменить имя целевой схемы.

Ответ 4

Это решение работает нормально, но оно не будет работать, если вы используете PHPunit для модульного тестирования.

Использование пароля в командной строке генерирует предупреждение, которое вызывается PHPUnit и генерирует исключение (да, довольно большое дело...)

Способ работы с этим - использовать файл конфигурации.

В моем случае я не хочу поддерживать пароль и пользователя как в файлах конфигурации, так и в PHP-коде, поэтому я генерирую конфигурационный файл из кода и проверяю, существует ли он (в противном случае я использую имя пользователя и пароль непосредственно в командной строки в качестве опции возврата).

Вот пример, в PHP, как скопировать базу данных установки для создания нового с другим именем (если вы, например, управляете основным доменом с другим субдоменом/базой данных для каждого вашего клиента):

/**
* 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;
}

Примечание:

  • Мне пришлось использовать двойную кавычку (") вместо одиночной кавычки (') вокруг моих операторов SQL.

  • Мне пришлось использовать амперсанд (&) для разделения моей другой команды.

  • В этом примере не включена проверка имени новой базы данных (метод isDestinationDbNameValid()). Не нужно упоминать, что вы никогда не должны доверять пользовательскому вводу...

  • Вам также нужно написать свой собственный метод для проверки того, что копия базы данных работала как ожидалось (метод isDestinationDbExist()). Вы должны хотя бы подтвердить, что база данных существует, существует таблица из вашей установки и, необязательно, проверять сохраненные программы.

Используйте мудро мудро своих друзей,

Джонатан Роланд-Левенк из Монреаля