同じmysqlデータベースインスタンスで現在のデータベースsitedb1
をsitedb2
にコピーするスクリプトを作成したいと思います。私は、sitedb1をsqlスクリプトにダンプできることを知っています。
mysqldump -u root -p sitedb1 >~/db_name.sql
そしてそれをsitedb2
にインポートします。最初のデータベースをSQLファイルにダンプせずに、簡単な方法はありますか?
マニュアルで データベースのコピー にあるように、mysqlクライアントに直接ダンプをパイプできます:
mysqldump db_name | mysql new_db_name
MyISAMを使用している場合は、ファイルをコピーできますが、お勧めしません。それは少し危険です。
さまざまな他の良い答えから統合された
mysqldump
とmysql
の両方のコマンドは、次のような接続詳細(およびその他)を設定するためのオプションを受け入れます。
mysqldump -u <user name> --password=<pwd> <original db> | mysql -u <user name> -p <new db>
また、新しいデータベースがまだ存在しない場合は、事前に作成する必要があります(例:echo "create database new_db_name" | mysql -u <dbuser> -p
)。
MySQLユーティリティには、ニースツール mysqldbcopy
が含まれています。これは、デフォルトで、関連するすべてのオブジェクト(「テーブル、ビュー、トリガー、イベント、プロシージャ、関数、データベースレベルの許可」)と1つのデータを含むDBをコピーします同じまたは別のDBサーバーへのDBサーバー。実際にコピーされるものをカスタマイズするために利用できる多くのオプションがあります。
したがって、OPの質問に答えるには:
mysqldbcopy \
--source=root:your_password@localhost \
--destination=root:your_password@localhost \
sitedb1:sitedb2
$ mysqladmin create DB_name -u DB_user --password=DB_pass && \
mysqldump -u DB_user --password=DB_pass DB_name | mysql -u DB_user --password=DB_pass -h DB_Host DB_name
端末/コマンドプロンプトからコマンドを実行する必要があります。
mysqldump -u <user name> -p <pwd> <original db> | mysql -u <user name> <pwd> <new db>
例:mysqldump -u root test_db1 | mysql -u root test_db2
これにより、test_db1がtest_db2にコピーされ、 'root' @ 'localhost'へのアクセスが許可されます。
最良かつ簡単な方法は、これらのコマンドを端末に入力し、rootユーザーにアクセス許可を設定することです。私のために働く..!
:~$> mysqldump -u root -p db1 > dump.sql
:~$> mysqladmin -u root -p create db2
:~$> mysql -u root -p db2 < dump.sql
あなたは(擬似コードで)使用することができます:
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 TABLE を参照してください。
最初に複製データベースを作成します。
CREATE DATABASE duplicateddb;
許可などがすべて整っていることを確認します。
mysqldump -u admin -p originaldb | mysql -u backup -p password duplicateddb;
次のようなことができます:
mysqldump -u[username] -p[password] database_name_for_clone
| mysql -u[username] -p[password] new_database_name
phpmyadminをインストールした場合の簡単な方法
データベースに移動し、「操作」タブを選択すると、「データベースのコピー先」ブロックが表示されます。それを使用すると、データベースをコピーできます。
このステートメントは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
mysqldbcopy
コマンドを使用して、データベースをあるサーバーから別のサーバーまたは同じサーバーにコピーすることをお勧めします。
mysqldbcopy --source=root:root@localhost --destination=root:root@localhost database-name:database-name-clone
Greg's answer で述べたように、mysqldump db_name | mysql new_db_name
は無料、安全、簡単データベース間でデータを転送する方法です。ただし、本当に遅いです。
データのバックアップを検討している場合、(このデータベースまたは他のデータベースで)データを失う余裕がない場合、またはinnodb
以外のテーブルを使用している場合は、mysqldump
を使用する必要があります。
開発用のものを探している場合、すべてのデータベースを別の場所にバックアップし、すべてがうまくいかなくなったときにmysql
を(おそらく手動で)パージおよび再インストールしても問題ない場合は、解決策があるかもしれません。
良い選択肢が見つからなかったので、自分でスクリプトを作成しました。私はa lotを費やしてこれを初めて動作させましたが、今では変更を加えるのが少し怖いです。 Innodbデータベースは、このようにコピーして貼り付けることを意図していませんでした。小さな変更は、これをすばらしい方法で失敗させます。コードを完成させて以来、問題はありませんでしたが、それはあなたがそうしないという意味ではありません。
テストされたシステム(ただし、まだ失敗する可能性があります):
Sudo
特権を取得し、データベースを複製するのに十分なストレージスペースがあることを確認しますmysqldump
との比較方法3GBのデータベースでは、mysqldump
とmysql
の使用には、マシンで40〜50分かかります。この方法を使用すると、同じプロセスに約8分しかかかりません。
SQLの変更はコードと一緒に保存され、アップグレードプロセスは本番と開発の両方で自動化されます。各変更セットは、エラーが発生した場合に復元するデータベースのバックアップを作成します。私たちが遭遇した問題の1つは、データベースの変更を伴う長期プロジェクトに取り組んでいて、バグを修正するために途中でブランチを切り替える必要があったときでした。
以前は、すべてのブランチに単一のデータベースを使用していたため、新しいデータベースの変更と互換性のないブランチに切り替えるたびにデータベースを再構築する必要がありました。そして、切り替えたときに、アップグレードを再度実行する必要がありました。
mysqldump
を使用して異なるブランチのデータベースを複製しようとしましたが、待機時間が長すぎ(40〜50分)、その間は何もできませんでした。
このソリューションにより、データベースのクローン作成時間が1/5に短縮されました(長い昼食の代わりにコーヒーとトイレの休憩を考えてください)。
互換性のないデータベースの変更があるブランチ間の切り替えには、単一のデータベースで50分以上かかりますが、mysqldump
またはこのコードを使用した初期セットアップ後はまったく時間がかかりません。このコードは、たまたまmysqldump
よりも5倍高速です。
いくつかの一般的なタスクと、それぞれの方法で大体どれくらいの時間がかかるかを示します。
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
すべてがスムーズに進むと、次のように表示されます。
Gregの答え に加えて、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
元のデータベースにトリガーがある場合、インポートの前に置換をパイピングすることにより、「トリガーが既に存在する」エラーを回避できます。
mysqldump -u olddbuser -p -d olddbname | sed "s/`olddbname`./`newdbname`./" | mysql -u newdbuser -p -D newdbname
これを行う方法はないと思います。 PHPMyAdminがこれを行うと、DBをダンプし、新しい名前で再挿入します。
ターミナルで「mysqldbcopy」を使用します。この場合は here といいます。例:cmdプロンプトを開始します。 mySql Serverのbinフォルダーに移動します。以下のクエリを実行します。
C:\Program Files\MySQL\MySQL Server 5.7\bin>mysqldbcopy --source=root:root@localhost --destination=root:root@localhost master:master_clone
ここで、localhostの「master」dbを「master_clone」にコピーしようとしています。