使用Mysql转储备份视图

问题描述 投票:24回答:7

我想只用mysqldump备份视图。

这可能吗?

如果是这样,怎么样?

mysql mysqldump
7个回答
23
投票

注意:Ken的答案从建议编辑转移到自己的答案。

这是使用上述变体的完整命令行示例

 mysql -u username INFORMATION_SCHEMA
  --skip-column-names --batch
  -e "select table_name from tables where table_type = 'VIEW'
      and table_schema = 'database'"
  | xargs mysqldump -u username database
  > views.sql

这将通过查询将所有视图名称提取到INFORMATION_SCHEMA数据库,然后将它们传递给xargs以制定mysqldump命令。需要使用--skip-column-names和--batch来使输出xargs友好。如果你有很多视图,这个命令行可能会太长,在这种情况下,你想要为select添加某种额外的过滤器(例如,查找以给定字符开头的所有视图)。


16
投票

我修改了Andomar's excellent answer以允许数据库(和其他设置)仅指定一次:

#!/bin/bash -e
mysql --skip-column-names --batch -e \
"select table_name from information_schema.views \
 where table_schema = database()" $* |
xargs --max-args 1 mysqldump $*

我把它保存为mysql-dump-views.sh并通过以下方式调用:

$ mysql-dump-views.sh -u user -ppassword databasename >dumpfile.sql

9
投票

只需使用information_schema即可轻松备份多个数据库的视图:

mysql --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, "; ") table_name from information_schema.views'

3
投票

通过备份,我假设你的意思是没有数据的定义。

现在似乎mysqldump没有区分VIEW和TABLE,所以最好的办法是在mysqldump的命令行上明确指定VIEW,或者在mysqldump之前动态找出这个列表,然后像以前一样将它传递下去。

您可以使用此查询获取特定数据库中的所有VIEW:

SHOW FULL TABLES WHERE table_type='view';


0
投票

我会像OP一样尽可能地密切关注mysqldump的输出,因为它包含了一些关于视图的信息,这些信息无法通过INFORMATION_SCHEMA中的简单查询重建。

这是我从源数据库创建部署视图脚本的方法:

SOURCEDB="my_source_db"
mysql $SOURCEDB --skip-column-names  -B -e \
"show full tables where table_type = 'view'" \
| awk '{print $1}' \
| xargs -I {} mysqldump $SOURCEDB {} > views.sql

0
投票

在回答这个问题方面,olliiiveranswer是最好的直接做到这一点。对于我的回答,我将尝试将其构建为全面的完整备份和还原解决方案。

借助这个问题中的其他答案以及其他一些资源,我想出了这个脚本,可以根据需要从生产服务器轻松替换我的开发服务器上的数据库。它一次只能在一个数据库上运行,而不是所有数据库。虽然我确实有一个单独的脚本,但在这里分享是不安全的,因为它基本上会删除并重新创建除了少数数据库之外的所有内容,并且您的环境可能会有所不同。

该脚本假定两台机器上的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

到目前为止它似乎工作,但你可能想要为你的目的调整它。请确保您的凭据文件位于何处,它具有安全访问权限,以便未经授权的用户无法读取它!

由于似乎很难正确导出视图,我修改了olliiiveranswer,以便首先删除任何表或视图,并在我们导入的数据库中使用有效视图的确切名称(如果存在),然后导入所有表,可能会错误地将这些视图创建为表,然后删除这些表并正确定义这些视图。

基本上这是它的工作原理:

  • 验证是否存在您在命令行上指定的数据库
  • 使用MYSQLDUMP创建转储文件
  • SCP将转储文件从生产转移到指定的测试服务器
  • 通过SSH在指定的测试服务器上发出import命令并返回输出
  • 完成后从两个服务器中删除转储文件
  • 在此过程中为大多数步骤发布一些合理的输出

-1
投票

谢谢你 - 非常有用。

虽然有一个打嗝 - 也许因为我有一些稍微复杂的观点来引用其他观点等等:

我发现“definer”用户需要存在并且对目标模式具有正确的权限,否则mysql将不会生成引用其他视图的视图,因为它的定义不足。

在生成的:

/ *!50013 DEFINER = <user> @ <host> SQL SECURITY DEFINER * /

- >确保<user> @ <host>在你的目标实例上没问题,或者用一个用户替换这个字符串。

谢谢托尔斯坦

© www.soinside.com 2019 - 2024. All rights reserved.