就回答这个问题而言,olliiiver 的answer 是最好的直接回答这个问题。对于我的回答,我将尝试将其构建为一个全面的完整备份和恢复解决方案。
在这个问题的其他答案和一些其他资源的帮助下,我想出了这个脚本,可以根据需要使用来自生产服务器的实时副本轻松替换我的开发服务器上的数据库。它一次在一个数据库上工作,而不是在所有数据库上工作。虽然我确实有一个单独的脚本,但在这里分享并不安全,因为它基本上会删除并重新创建除了少数几个数据库之外的所有内容,并且您的环境可能会有所不同。
脚本假定两台机器上的 root 系统和 MySQL 用户(尽管可以更改),在服务器之间工作无密码 SSH,并依赖于每台机器上的 MySQL 密码文件 /root/mysqlroot.cnf,如下所示:
[client]
password=YourPasswordHere
文件:synctestdb.sh,可选择符号链接到 /usr/sbin/synctestdb 以方便使用
Usage: synctestdb DBNAME DESTSERVER
从生产服务器运行它。
这里是:
#!/bin/bash
if [ "${1}" != "" ] && [ "${1}" != "--help" ] && [ "${2}" != "" ] ; then
DBNAME=${1}
DESTSERVER=${2}
BKDATE=$( date "+%Y-%m-%d" );
SRCHOSTNAME=$( /bin/hostname )
EXPORTPATH=/tmp
EXPORTFILE=/tmp/${SRCHOSTNAME}_sql_${BKDATE}_devsync.sql
CREDSFILE=/root/mysqlroot.cnf
SSHUSER=root
DBEXISTS=$( echo "SHOW DATABASES LIKE '${DBNAME}'" \
| mysql --defaults-extra-file=${CREDSFILE} -NB INFORMATION_SCHEMA )
if [ "${DBEXISTS}" == "${DBNAME}" ] ; then
echo Preparing --ignore-tables parameters for all relevant views
echo
#build --ignore-table parameters list from list of all views in
#relevant database - as mysqldump likes to recreate views as tables
#we pair this with an export of the view definitions later below
SKIPVIEWS=$(mysql --defaults-extra-file=${CREDSFILE} \
-NB \
-e "SELECT \
CONCAT( '--ignore-table=', TABLE_SCHEMA, '.', TABLE_NAME ) AS q \
FROM INFORMATION_SCHEMA.VIEWS \
WHERE TABLE_SCHEMA = '${DBNAME}';" )
if [ "$?" == "0" ] ; then
echo Exporting database ${DBNAME}
echo
mysqldump --defaults-extra-file=${CREDSFILE} ${SKIPVIEWS} \
--add-locks --extended-insert --flush-privileges --no-autocommit \
--routines --triggers --single-transaction --master-data=2 \
--flush-logs --events --quick --databases ${DBNAME} > ${EXPORTFILE} \
|| echo -e "\n\nERROR: ${SRCHOSTNAME} failed to mysqldump ${DBNAME}"
echo Exporting view definitions
echo
mysql --defaults-extra-file=${CREDSFILE} \
--skip-column-names --batch \
-e "SELECT \
CONCAT( \
'DROP TABLE IF EXISTS ', TABLE_SCHEMA, '.', TABLE_NAME, \
'; CREATE OR REPLACE VIEW ', TABLE_SCHEMA, '.', TABLE_NAME, ' AS ', \
VIEW_DEFINITION, '; ') AS TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS \
WHERE TABLE_SCHEMA = '${DBNAME}';" >> ${EXPORTFILE} \
|| echo -e "\n\nERROR: ${SRCHOSTNAME} failed to mysqldump view definitions"
echo Export complete, preparing to transfer export file and import
echo
STATUSMSG="SUCCESS: database ${DBNAME} synced from ${SRCHOSTNAME} to ${DESTSERVER}"
scp \
${EXPORTFILE} \
${SSHUSER}@${DESTSERVER}:${EXPORTPATH}/ \
|| STATUSMSG="ERROR: Failed to SCP file to remote server ${DESTSERVER}"
ssh ${SSHUSER}@${DESTSERVER} \
"mysql --defaults-extra-file=${CREDSFILE} < ${EXPORTFILE}" \
|| STATUSMSG="ERROR: Failed to update remote server ${DESTSERVER}"
ssh ${SSHUSER}@${DESTSERVER} \
"rm ${EXPORTFILE}" \
|| STATUSMSG="ERROR: Failed to remove import file from remote server ${DESTSERVER}"
rm ${EXPORTFILE}
echo ${STATUSMSG}
else
echo "ERROR: could not obtain list of views from INFORMATION_SCHEMA"
fi
else
echo "ERROR: specified database not found, or SQL credentials file not found"
fi
else
echo -e "Usage: synctestdb DBNAME DESTSERVER \nPlease only run this script from the live production server\n"
fi
到目前为止,它似乎可以工作,尽管您可能需要根据自己的目的对其进行调整。确保无论您的凭据文件在哪里,都设置了安全访问权限,以便未经授权的用户无法读取它!
由于正确导出视图似乎很困难,我调整了 olliiiver 的 answer 以使其首先删除所有表或视图,这些表或视图与我们要导入的数据库中的有效视图的确切名称相同如果它们存在,则导入所有表,这可能会错误地将这些视图创建为表,然后删除这些表并正确定义这些视图。
基本上是这样的:
- 验证您在命令行中指定的数据库是否存在
- 使用 MYSQLDUMP 创建转储文件
- SCP 转储文件从生产到指定的测试服务器
- 通过 SSH 在指定的测试服务器上发出导入命令并返回输出
- 完成后从两台服务器中删除转储文件
- 为沿途的大多数步骤发出一些合理的输出