Как дублировать базу данных MySQL на том же сервере - PullRequest
49 голосов
/ 11 июля 2011

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

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

С уважением,

CGD

Ответы [ 6 ]

72 голосов
/ 11 июля 2011

Клиент командной строки 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

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

6 голосов
/ 20 апреля 2015

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

Чтобы скопировать эти несколько параметров, требуется 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

0 голосов
/ 29 мая 2019

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

Другая возможность, если у вас есть свободное место -и, в настоящее время, 20 Гб это не так много - это использование вспомогательной базы данных.

Вы можете установить вторую копию MySQL Server на другой порт, и это будетраб.Тогда у вас будет две идентичные базы данных (живой мастер, работающий подчиненный).

Когда вам нужно клонировать тестовую базу данных, остановите репликацию подчиненного устройства - живой подчиненный теперь будет оставаться «замороженным» во времени - и сделайте резервную копиюживой раб к тестовой базе данных, используя MySQLbackup или просто копируя файлы данных.После этого вы перезапускаете репликацию.

Влияние на работающий мастер незначительно, и ведомое устройство может фактически использоваться для выбора, не критичного для обновления.

0 голосов
/ 29 мая 2019

Для всех пользователей Mac, с sequel pro все, что вам нужно сделать, это зайти в базу данных (меню) -> Дублировать базу данных. Готово!

0 голосов
/ 20 июля 2015

Это решение отлично работает, но оно не сработает, если вы используете 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;
}

Дополнительные примечания:

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

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

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

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

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

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

0 голосов
/ 09 октября 2014

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

...