Резервное копирование просмотров с помощью Mysql Dump - PullRequest
25 голосов
/ 01 ноября 2009

Я хочу сделать резервную копию только просмотров с помощью mysqldump.

Возможно ли это?

Если да, то как?

Ответы [ 7 ]

23 голосов
/ 20 июня 2012

ПРИМЕЧАНИЕ. Этот ответ от Кен перемещен из предложенного редактирования в собственный ответ.

вот полный пример командной строки с использованием варианта выше

 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. Эта командная строка может быть слишком длинной, если у вас много представлений, и в этом случае вы захотите добавить какой-то дополнительный фильтр к выделению (например, искать все представления, начинающиеся с данного символа).

16 голосов
/ 30 апреля 2013

Я изменил Отличный ответ Andomar , чтобы разрешить указание базы данных (и других настроек) только один раз:

#!/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 голосов
/ 14 августа 2015

Резервное копирование представлений в нескольких базах данных легко, просто используя 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 голосов
/ 01 ноября 2009

Под резервным копированием я предполагаю, что вы имеете в виду только определение без данных.

Кажется, что сейчас mysqldump не различает VIEWs и TABLE, поэтому, возможно, лучше всего либо явно указать VIEWs в командной строке для mysqldump, либо динамически определить этот список перед mysqldump, а затем передать его вниз как прежде.

Вы можете получить все ВИДЫ в конкретной базе данных, используя этот запрос:

SHOW FULL TABLES WHERE table_type='view';

0 голосов
/ 17 апреля 2019

С точки зрения ответа на этот вопрос, olliiiver ' answer - лучший способ сделать это напрямую. В качестве ответа я постараюсь встроить это в комплексное решение для полного резервного копирования и восстановления.

С помощью других ответов на этот вопрос и нескольких других ресурсов я придумал этот сценарий для простой замены базы данных на моем сервере разработки оперативной копией с рабочего сервера по требованию. Он работает на одной базе данных за раз, а не на всех базах данных. Хотя у меня есть отдельный скрипт для этого, здесь небезопасно делиться, так как он в основном отбрасывает и воссоздает все, кроме нескольких избранных баз данных, и ваша среда может отличаться.

Сценарий предполагает наличие корневой системы и пользователя 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 и возвращает результат
  • удалить файл дампа с обоих серверов после завершения
  • выдает разумный вывод для большинства шагов по пути
0 голосов
/ 10 марта 2017

Я бы как можно точнее придерживался вывода mysqldump , как запросил OP, поскольку он включает в себя множество информации о представлении, которое невозможно восстановить простым запросом из 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 голосов
/ 07 сентября 2015

Спасибо за это - очень полезно.

Хотя один сбой - возможно, потому что у меня есть немного запутанный набор представлений, которые ссылаются на другие представления и т. Д .:

Я обнаружил, что «определенный» пользователь должен существовать и иметь права доступа к целевой схеме, в противном случае mysql не будет генерировать представления, которые ссылаются на другие представления, так как его определения недостаточно.

В сгенерированном:

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

-> убедиться, что <user> @ <host> подходит для вашего целевого экземпляра, или замените эту строку на пользователя, который делает.

Спасибо Торстейн

...