Я хотел бы написать сценарий, который копирует мою текущую базу данных sitedb1
в sitedb2
тот же экземпляр базы данных mysql. Я знаю, что могу сбросить sitedb1 в sql-скрипт:
mysqldump -u root -p sitedb1 >~/db_name.sql
а затем импортируйте его в sitedb2
. Есть ли более простой способ без сброса первой базы данных в файл sql?
Ответы:
Как говорится в руководстве в разделе « Копирование баз данных», вы можете передать дамп прямо в клиент mysql:
Если вы используете MyISAM, вы можете копировать файлы, но я бы не рекомендовал это. Это немного хитроумно.
Интегрировано из различных хороших других ответов
Как
mysqldump
иmysql
команды принимают параметры для настройки соединения деталей (и многих других), как:Кроме того, если новой базы данных еще нет, ее необходимо создать заранее (например, с помощью
echo "create database new_db_name" | mysql -u <dbuser> -p
).источник
mysqldump -uroot -p database1 | mysql -uroot -p database2
. Мне предлагается ввести оба пароля, но я могу ввести только один. Контекстное выглядит следующим образом :Enter password: Enter password:
. После выдачи первого pw процесс ждет вечно.Использование утилит MySQL
Утилиты MySQL содержат прекрасный инструмент,
mysqldbcopy
который по умолчанию копирует БД, включая все связанные объекты («таблицы, представления, триггеры, события, процедуры, функции и гранты уровня базы данных») и данные с одного сервера БД на тот же или на другой. Сервер БД. Существует множество опций для настройки того, что фактически копируется.Итак, чтобы ответить на вопрос OP:
mysqldbcopy \ --source=root:your_password@localhost \ --destination=root:your_password@localhost \ sitedb1:sitedb2
источник
mysqldump
решение на основе не удалось.sudo apt-get install mysql-utilities
, но это очень аккуратно. Могу ли я не указывать пароль, и мне будет предложено его ввести?mysqldbcopy
вам запросить пароль; по крайней мере, я не нашел ничего подобного в документации. Однако вы можете создать эту функцию самостоятельно. В Bash это может выглядеть примерно так:mysqldbcopy --source=root:"$(read -sp 'Source password: ' && echo $REPLY)"@localhost --destination=root:"$(read -sp 'Destination password: ' && echo $REPLY)"@localhost sitedb1:sitedb2
--force
вmysqldbcopy
команду, потому что я уже создал целевую базу данных. Благодарность!источник
Лучший и простой способ - ввести эти команды в свой терминал и установить разрешения для пользователя root. Работает для меня..!
:~$> mysqldump -u root -p db1 > dump.sql :~$> mysqladmin -u root -p create db2 :~$> mysql -u root -p db2 < dump.sql
источник
mysqldump -u <user> -p <pwd> db_name | mysql -u <user> -p <pwd> new_db_name
может вызывать проблемы с большими базами данных.Вам нужно запустить команду из терминала / командной строки.
например:
mysqldump -u root test_db1 | mysql -u root test_db2
Это копирует test_db1 в test_db2 и предоставляет доступ к 'root' @ 'localhost'
источник
Вы можете использовать (в псевдокоде):
FOREACH tbl IN db_a: CREATE TABLE db_b.tbl LIKE db_a.tbl; INSERT INTO db_b.tbl SELECT * FROM db_a.tbl;
Причина, по которой я не использую синтаксис CREATE TABLE ... SELECT ..., заключается в сохранении индексов. Конечно, это копирует только таблицы. Представления и процедуры не копируются, хотя это можно сделать таким же образом.
См. СОЗДАТЬ ТАБЛИЦУ .
источник
Сначала создайте дубликат базы данных:
CREATE DATABASE duplicateddb;
Убедитесь, что все разрешения и т. Д. Установлены, и:
mysqldump -u admin -p originaldb | mysql -u backup -p password duplicateddb;
источник
Вы можете сделать что-то вроде следующего:
источник
Этот оператор был добавлен в MySQL 5.1.7, но был признан опасным и был удален в MySQL 5.1.23. Он был предназначен для обеспечения возможности обновления баз данных до 5.1 для использования кодировки, реализованной в 5.1, для отображения имен баз данных на имена каталогов баз данных. Однако использование этого оператора могло привести к потере содержимого базы данных, поэтому он был удален. Не используйте RENAME DATABASE в более ранних версиях, в которых она присутствует.
Чтобы выполнить задачу обновления имен баз данных с помощью новой кодировки, используйте вместо этого ALTER DATABASE db_name UPGRADE DATA DIRECTORY NAME: http://dev.mysql.com/doc/refman/5.1/en/alter-database.html
источник
Простой способ сделать это, если вы установили phpmyadmin :
Зайдите в свою базу данных, выберите вкладку «операция», и вы увидите блок «копировать базу данных в». Воспользуйтесь им, и вы сможете скопировать базу данных.
источник
Как упоминалось в ответе Грега ,
mysqldump db_name | mysql new_db_name
это бесплатный, безопасный и простой способ передачи данных между базами данных. Однако это также очень медленно .Если вы хотите сделать резервную копию данных, не можете позволить себе потерять данные (в этой или других базах данных) или используете другие таблицы
innodb
, то вам следует использоватьmysqldump
.Если вы ищете что-то для разработки, у вас есть резервные копии всех ваших баз данных в другом месте, и вам удобно очищать и переустанавливать
mysql
(возможно, вручную), когда все идет не так, то у меня, возможно, есть решение для вас.Мне не удалось найти хорошей альтернативы, поэтому я создал сценарий, чтобы сделать это сам. Я потратил много времени на то, чтобы заставить это работать в первый раз, и, честно говоря, меня немного пугает то, что я сейчас меняю его. Базы данных Innodb не предназначены для такого копирования и вставки. Небольшие изменения приводят к великолепным сбоям. У меня не было проблем с тех пор, как я завершил код, но это не значит, что вы не будете этого делать.
Системы протестированы (но все еще могут не работать):
Что оно делает
sudo
привилегию и проверяет, достаточно ли у вас места для клонирования базы данных.Как это сравнить с
mysqldump
В базе данных 3 ГБ использование
mysqldump
иmysql
на моей машине займет 40-50 минут. Используя этот метод, тот же процесс займет всего ~ 8 минут.Как мы это используем
Мы сохраняем наши изменения SQL вместе с нашим кодом, и процесс обновления автоматизирован как при производстве, так и при разработке, при этом каждый набор изменений создает резервную копию базы данных для восстановления в случае ошибок. Одна из проблем, с которой мы столкнулись, заключалась в том, что когда мы работали над долгосрочным проектом с изменениями базы данных, и нам приходилось переключать ветки в середине, чтобы исправить одну или три ошибки.
Раньше мы использовали единую базу данных для всех ветвей, и нам приходилось перестраивать базу данных всякий раз, когда мы переключались на ветку, несовместимую с новыми изменениями базы данных. А когда мы вернемся обратно, нам придется снова запускать обновления.
Мы пытались
mysqldump
продублировать базу данных для разных веток, но время ожидания было слишком долгим (40-50 минут), и мы не могли пока ничего сделать.Это решение сократило время клонирования базы данных до 1/5 времени (подумайте о перерыве на кофе и в ванной вместо длинного обеда).
Общие задачи и их время
Переключение между ветвями с несовместимыми изменениями базы данных занимает более 50 минут для одной базы данных, но совсем не после времени начальной настройки с помощью
mysqldump
или этого кода. Этот код оказывается примерно в 5 раз быстрее, чемmysqldump
.Вот несколько распространенных задач и примерное время, которое потребуется для каждого метода:
Создайте функциональную ветку с изменениями базы данных и немедленно объедините:
mysqldump
: 50-60 минутСоздайте функциональную ветку с изменениями базы данных, переключитесь на
master
исправление ошибки, отредактируйте функциональную ветку и объедините:mysqldump
: 50-60 минутСоздайте функциональную ветку с изменениями базы данных, переключитесь на
master
исправление ошибки 5 раз, внося изменения в функциональную ветку между ними, и выполните слияние:mysqldump
: 50-60 минутКод
Не используйте это, если вы не прочитали и не поняли все выше.
#!/bin/bash set -e # This script taken from: https://stackoverflow.com/a/57528198/526741 function now { date "+%H:%M:%S"; } # Leading space sets messages off from step progress. echosuccess () { printf "\e[0;32m %s: %s\e[0m\n" "$(now)" "$1" sleep .1 } echowarn () { printf "\e[0;33m %s: %s\e[0m\n" "$(now)" "$1" sleep .1 } echoerror () { printf "\e[0;31m %s: %s\e[0m\n" "$(now)" "$1" sleep .1 } echonotice () { printf "\e[0;94m %s: %s\e[0m\n" "$(now)" "$1" sleep .1 } echoinstructions () { printf "\e[0;104m %s: %s\e[0m\n" "$(now)" "$1" sleep .1 } echostep () { printf "\e[0;90mStep %s of 13:\e[0m\n" "$1" sleep .1 } MYSQL_CNF_PATH='/etc/mysql/mysql.conf.d/recovery.cnf' OLD_DB='YOUR_DATABASE_NAME' USER='YOUR_MYSQL_USER' # You can change NEW_DB to whatever you like # Right now, it will append the current git branch name to the existing database name BRANCH=`git rev-parse --abbrev-ref HEAD` NEW_DB="${OLD_DB}__$BRANCH" THIS_DIR=./site/upgrades DB_CREATED=false tmp_file () { printf "$THIS_DIR/$NEW_DB.%s" "$1" } sql_on_new_db () { mysql $NEW_DB --unbuffered --skip-column-names -u root -p$PASS 2>> $(tmp_file 'errors.log') } general_cleanup () { echoinstructions 'Leave this running while things are cleaned up...' if [ -f $(tmp_file 'errors.log') ]; then echowarn 'Additional warnings and errors:' cat $(tmp_file 'errors.log') fi for f in $THIS_DIR/$NEW_DB.*; do echonotice 'Deleting temporary files created for transfer...' rm -f $THIS_DIR/$NEW_DB.* break done echonotice 'Done!' echoinstructions "You can close this now :)" } error_cleanup () { exitcode=$? # Just in case script was exited while in a prompt echo if [ "$exitcode" == "0" ]; then echoerror "Script exited prematurely, but exit code was '0'." fi echoerror "The following command on line ${BASH_LINENO[0]} exited with code $exitcode:" echo " $BASH_COMMAND" if [ "$DB_CREATED" = true ]; then echo echonotice "Dropping database \`$NEW_DB\` if created..." echo "DROP DATABASE \`$NEW_DB\`;" | sql_on_new_db || echoerror "Could not drop database \`$NEW_DB\` (see warnings)" fi general_cleanup exit $exitcode } trap error_cleanup EXIT mysql_path () { printf "/var/lib/mysql/" } old_db_path () { printf "%s%s/" "$(mysql_path)" "$OLD_DB" } new_db_path () { printf "%s%s/" "$(mysql_path)" "$NEW_DB" } get_tables () { (sudo find /var/lib/mysql/$OLD_DB -name "*.frm" -printf "%f\n") | cut -d'.' -f1 | sort } STEP=0 authenticate () { printf "\e[0;104m" sudo ls &> /dev/null printf "\e[0m" echonotice 'Authenticated.' } echostep $((++STEP)) authenticate TABLE_COUNT=`get_tables | wc -l` SPACE_AVAIL=`df -k --output=avail $(mysql_path) | tail -n1` SPACE_NEEDED=(`sudo du -s $(old_db_path)`) SPACE_ERR=`echo "$SPACE_AVAIL-$SPACE_NEEDED" | bc` SPACE_WARN=`echo "$SPACE_AVAIL-$SPACE_NEEDED*3" | bc` if [ $SPACE_ERR -lt 0 ]; then echoerror 'There is not enough space to branch the database.' echoerror 'Please free up some space and run this command again.' SPACE_AVAIL_FORMATTED=`printf "%'d" $SPACE_AVAIL` SPACE_NEEDED_FORMATTED=`printf "%'${#SPACE_AVAIL_FORMATTED}d" $SPACE_NEEDED` echonotice "$SPACE_NEEDED_FORMATTED bytes needed to create database branch" echonotice "$SPACE_AVAIL_FORMATTED bytes currently free" exit 1 elif [ $SPACE_WARN -lt 0 ]; then echowarn 'This action will use more than 1/3 of your available space.' SPACE_AVAIL_FORMATTED=`printf "%'d" $SPACE_AVAIL` SPACE_NEEDED_FORMATTED=`printf "%'${#SPACE_AVAIL_FORMATTED}d" $SPACE_NEEDED` echonotice "$SPACE_NEEDED_FORMATTED bytes needed to create database branch" echonotice "$SPACE_AVAIL_FORMATTED bytes currently free" printf "\e[0;104m" read -p " $(now): Do you still want to branch the database? [y/n] " -n 1 -r CONFIRM printf "\e[0m" echo if [[ ! $CONFIRM =~ ^[Yy]$ ]]; then echonotice 'Database was NOT branched' exit 1 fi fi PASS='badpass' connect_to_db () { printf "\e[0;104m %s: MySQL root password: \e[0m" "$(now)" read -s PASS PASS=${PASS:-badpass} echo echonotice "Connecting to MySQL..." } create_db () { echonotice 'Creating empty database...' echo "CREATE DATABASE \`$NEW_DB\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" | mysql -u root -p$PASS 2>> $(tmp_file 'errors.log') DB_CREATED=true } build_tables () { echonotice 'Retrieving and building database structure...' mysqldump $OLD_DB --skip-comments -d -u root -p$PASS 2>> $(tmp_file 'errors.log') | pv --width 80 --name " $(now)" > $(tmp_file 'dump.sql') pv --width 80 --name " $(now)" $(tmp_file 'dump.sql') | sql_on_new_db } set_debug_1 () { echonotice 'Switching into recovery mode for innodb...' printf '[mysqld]\ninnodb_file_per_table = 1\ninnodb_force_recovery = 1\n' | sudo tee $MYSQL_CNF_PATH > /dev/null } set_debug_0 () { echonotice 'Switching out of recovery mode for innodb...' sudo rm -f $MYSQL_CNF_PATH } discard_tablespace () { echonotice 'Unlinking default data...' ( echo "USE \`$NEW_DB\`;" echo "SET foreign_key_checks = 0;" get_tables | while read -r line; do echo "ALTER TABLE \`$line\` DISCARD TABLESPACE; SELECT 'Table \`$line\` imported.';"; done echo "SET foreign_key_checks = 1;" ) > $(tmp_file 'discard_tablespace.sql') cat $(tmp_file 'discard_tablespace.sql') | sql_on_new_db | pv --width 80 --line-mode --size $TABLE_COUNT --name " $(now)" > /dev/null } import_tablespace () { echonotice 'Linking imported data...' ( echo "USE \`$NEW_DB\`;" echo "SET foreign_key_checks = 0;" get_tables | while read -r line; do echo "ALTER TABLE \`$line\` IMPORT TABLESPACE; SELECT 'Table \`$line\` imported.';"; done echo "SET foreign_key_checks = 1;" ) > $(tmp_file 'import_tablespace.sql') cat $(tmp_file 'import_tablespace.sql') | sql_on_new_db | pv --width 80 --line-mode --size $TABLE_COUNT --name " $(now)" > /dev/null } stop_mysql () { echonotice 'Stopping MySQL...' sudo /etc/init.d/mysql stop >> $(tmp_file 'log') } start_mysql () { echonotice 'Starting MySQL...' sudo /etc/init.d/mysql start >> $(tmp_file 'log') } restart_mysql () { echonotice 'Restarting MySQL...' sudo /etc/init.d/mysql restart >> $(tmp_file 'log') } copy_data () { echonotice 'Copying data...' sudo rm -f $(new_db_path)*.ibd sudo rsync -ah --info=progress2 $(old_db_path) --include '*.ibd' --exclude '*' $(new_db_path) } give_access () { echonotice "Giving MySQL user \`$USER\` access to database \`$NEW_DB\`" echo "GRANT ALL PRIVILEGES ON \`$NEW_DB\`.* to $USER@localhost" | sql_on_new_db } echostep $((++STEP)) connect_to_db EXISTING_TABLE=`echo "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$NEW_DB'" | mysql --skip-column-names -u root -p$PASS 2>> $(tmp_file 'errors.log')` if [ "$EXISTING_TABLE" == "$NEW_DB" ] then echoerror "Database \`$NEW_DB\` already exists" exit 1 fi echoinstructions "The hamsters are working. Check back in 5-10 minutes." sleep 5 echostep $((++STEP)) create_db echostep $((++STEP)) build_tables echostep $((++STEP)) set_debug_1 echostep $((++STEP)) discard_tablespace echostep $((++STEP)) stop_mysql echostep $((++STEP)) copy_data echostep $((++STEP)) start_mysql echostep $((++STEP)) import_tablespace echostep $((++STEP)) set_debug_0 echostep $((++STEP)) restart_mysql echostep $((++STEP)) give_access echo echosuccess "Database \`$NEW_DB\` is ready to use." echo trap general_cleanup EXIT
Если все пройдет гладко, вы должны увидеть что-то вроде:
источник
В дополнение к ответу Грега это самый простой и быстрый способ, если
new_db_name
он еще не существует:echo "create database new_db_name" | mysql -u <user> -p <pwd> mysqldump -u <user> -p <pwd> db_name | mysql -u <user> -p <pwd> new_db_name
источник
Если у вас есть триггеры в исходной базе данных, вы можете избежать ошибки «Триггер уже существует», установив замену перед импортом:
источник
Я не думаю, что есть способ сделать это. Когда PHPMyAdmin делает это, он выгружает БД, а затем повторно вставляет ее под новым именем.
источник