如何在同一台服务器上复制MySQL数据库
我有一个很大的MySQL数据库,我们把它live_db
,我想在同一台机器上复制这个数据库,以提供一个testing系统( test_db
),包括表结构和数据。 在有规律的时间间隔,我想用test_db
的内容来更新live_db
; 如果可能的话增量
在MySQL中有一些内置的机制来做到这一点? 我认为主从复制不是我想要的,因为应该可以在test_db
修改数据。 不过,这些变化不一定要保留。
问候,
CGD
mysql
命令行客户端将接受来自标准input的SQL语句stream。 因此,您可以在命令行上直接将mysqldump
的输出传输到mysql
。 以cron工作方式执行此操作将定期用更新的实时数据覆盖您的testing数据:
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
请注意,由于您的数据很大,所以需要很长时间。
Michaels回答很好,但不会复制事件,存储过程或触发器。
为了复制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
如果您更喜欢MySQL Migration Toolkit,则可以在“数据映射”步骤中双击模式名称,然后更改目标模式名称。
这个解决scheme可以正常工作,但是如果你使用PHPunit进行unit testing,那么这个解决scheme是不会做的。
在命令行中使用密码会生成一个警告,PHPUnit会捕获这个警告,并生成一个exception(是非常重要的…)
解决这个问题的方法是使用configuration文件。
在我的情况下,我不想在configuration文件和PHP代码中维护密码和用户,所以我从代码生成configuration文件,并检查它是否存在(否则我直接在命令行中使用用户名和密码作为回退选项)。
下面是一个例子,在PHP中,如何复制安装数据库以创build一个不同名称的新数据库(例如,如果您是为每个客户使用不同的子域/数据库pipe理主域):
/** * 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()方法)的validation。 没必要提到你永远不要相信用户input…
-
您还必须编写自定义方法来validation数据库副本是否按预期工作(isDestinationDbExist()方法)。 您至less应该validation数据库是否存在,从您的设置中存在一个表,并可以selectvalidation存储的程序。
明智地使用武力我的朋友,
来自蒙特利尔的Jonathan Parent-Lévesque