उसी MySql उदाहरण पर MySQL डेटाबेस का क्लोनिंग


154

मैं एक स्क्रिप्ट लिखना चाहूंगा जो मेरे वर्तमान डेटाबेस sitedb1को sitedb2उसी mysql डेटाबेस उदाहरण पर कॉपी करे । मुझे पता है कि मैं sitedb1 को एक sql स्क्रिप्ट में डंप कर सकता हूं:

mysqldump -u root -p sitedb1 >~/db_name.sql

और फिर इसे आयात करें sitedb2। वहाँ एक आसान तरीका है, एक sql फ़ाइल के लिए पहले डेटाबेस डंपिंग के बिना?


जवाबों:


303

जैसा कि मैनुअल कहता है प्रतिलिपि डेटाबेस में आप डंप को सीधे 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)।


2
Kinda ... यह डिस्क IO का एक बहुत कुछ छोड़ देता है, हालांकि आपको डेटा को दो बार पढ़ने / लिखने की ज़रूरत नहीं है
ग्रेग

8
यदि आपका डेटाबेस आकार में विशाल है तो यह संभवतः आपको अधिक लाभ नहीं देगा। मुझे लगता है कि ओपी मिल रहा है, वे प्रतिलिपि को बाहरी नहीं करना चाहते हैं: क्या यह विशुद्ध रूप से mysql के भीतर किया जा सकता है?
cletus

3
मैं कहूंगा कि डीबी जितना बड़ा होगा उतना ही आपको फायदा होगा ... MySQL afaik के भीतर ऐसा करने का कोई तरीका नहीं है (एक समय में हाथ, एक तालिका / दृश्य को छोड़कर)
ग्रेग

41
मुझे पहली बार new_db को मानक mysql कमांड का उपयोग करके बनाना था: "DATEABASE नया_db बनाएँ;" और फिर इन कमांड का इस्तेमाल किया: mysqldump -u root -p old_db | mysql -u root -p new_db
वेलेंटाइन

4
यह मेरे लिए काम नहीं करता है, अगर मैं डंपिंग और इस तरह आयात करने के लिए पासवर्ड में डाल करने के लिए है: mysqldump -uroot -p database1 | mysql -uroot -p database2। मुझे दोनों pws के लिए संकेत मिलता है, लेकिन केवल एक में ही डाल सकते हैं। प्रॉम्प्ट इस तरह दिखता है Enter password: Enter password: :। पहला पाव देने के बाद, प्रक्रिया हमेशा के लिए प्रतीक्षा करती है।
टॉरस्टेन

66

MySQL यूटिलिटीज का उपयोग करना

MySQL यूटिलिटीज में अच्छा टूल है mysqldbcopy होता है जो डिफ़ॉल्ट रूप से सभी संबंधित वस्तुओं ("तालिकाओं, विचारों, ट्रिगर, घटनाओं, प्रक्रियाओं, कार्यों और डेटाबेस-स्तरीय अनुदान") सहित एक DB को कॉपी करता है और एक DB सर्वर से उसी या दूसरे को डेटा DB सर्वर। वास्तव में प्रतिलिपि बनाई गई अनुकूलित करने के लिए बहुत सारे विकल्प उपलब्ध हैं।

तो, ओपी के सवाल का जवाब देने के लिए:

mysqldbcopy \
    --source=root:your_password@localhost \
    --destination=root:your_password@localhost \
    sitedb1:sitedb2

1
यह मेरे लिए ठीक काम करता था, mysqldumpआधारित समाधान विफल हो रहा था।
सजीओ 89

1
मेरे मामले में मुझे इस तरह से पोर्ट निर्दिष्ट करना था: - स्रोत = रूट: your_password @ localhost: 3307 (अन्यथा यह मुझे एक पहुंच अस्वीकृत त्रुटि देगा)
pbz

4
जरूरत है sudo apt-get install mysql-utilities, लेकिन यह बहुत साफ है। क्या मैं पासवर्ड छोड़ सकता हूं और इसे दर्ज करने के लिए कहा जा सकता हूं?
ADTC

2
@ADTC मुझे नहीं पता mysqldbcopyकि पासवर्ड के लिए आपसे पूछने के लिए कोई अंतर्निहित तरीका है ; कम से कम मुझे प्रलेखन में ऐसा कुछ नहीं मिला। आप इस कार्यक्षमता का निर्माण स्वयं कर सकते हैं, यद्यपि। बैश में जो कुछ इस तरह दिख सकता था:mysqldbcopy --source=root:"$(read -sp 'Source password: ' && echo $REPLY)"@localhost --destination=root:"$(read -sp 'Destination password: ' && echo $REPLY)"@localhost sitedb1:sitedb2
Chriki

1
FYI करें: ऐसा लगता है कि Chriki की कमान निर्दोष रूप से काम करती है। मैं तो बस जोड़ने के लिए किया था --forceकरने के लिए mysqldbcopyआदेश है क्योंकि मैं पहले से ही गंतव्य डेटाबेस बनाया था। धन्यवाद!
Niavlys

19
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

2
स्वीकृत उत्तर में यह क्या जोड़ता है? समान है, लेकिन आप कुछ अंतर जोड़ते हैं, बेहतर समझ के लिए कुछ टिप्पणियां जोड़ते हैं
यारोस्लाव

यह स्वीकृत उत्तर होना चाहिए, क्योंकि यह डेटाबेस का निर्माण करेगा, जो कि ऑर्कुट के लिए भी अच्छा है। वर्तमान स्वीकृत उत्तर आपको अस्वीकृत होने की सूचना देगा, तब तालिका मौजूद नहीं है।
रामी दबैन

14

आपको टर्मिनल / कमांड प्रॉम्प्ट से कमांड चलाने की आवश्यकता है।

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 पर कॉपी करता है और 'रूट' @ 'लोकलहोस्ट' को एक्सेस प्रदान करता है


मुझे यह जवाब पसंद है, यह कुरकुरा है। हालाँकि, मेरे लिए पासवर्ड से पहले mysql आवश्यक -p है।
lwitzel

1
हम मूल डेटाबेस में बनाए गए कार्यों, घटनाओं आदि की प्रतिलिपि कैसे बना सकते हैं? यह केवल प्रतियां तालिकाओं को देखता है।
डोगन आस्कन

12

सबसे अच्छा और आसान तरीका अपने टर्मिनल में इन कमांड को दर्ज करना है और रूट उपयोगकर्ता को अनुमतियाँ सेट करना है। मेरे लिये कार्य करता है..!

:~$> mysqldump -u root -p db1 > dump.sql
:~$> mysqladmin -u root -p create db2
:~$> mysql -u root -p db2 < dump.sql

1
यह प्रश्न स्पष्ट रूप से कहा गया है कि निर्यात / आयात विधि पहले से ही ज्ञात है।
लव

3
यह इसे करने का सबसे अच्छा तरीका है। बड़े डेटाबेस के साथ भी काम करता है, जबकि पाइप संस्करण mysqldump -u <user> -p <pwd> db_name | mysql -u <user> -p <pwd> new_db_nameबड़े डेटाबेस के साथ समस्याग्रस्त हो सकता है।
एलेक्स

10

आप उपयोग कर सकते हैं (pseudocode में):

FOREACH tbl IN db_a:
    CREATE TABLE db_b.tbl LIKE db_a.tbl;
    INSERT INTO db_b.tbl SELECT * FROM db_a.tbl;

कारण मैं क्रिएट टेबल ... सिलेक्ट ... सिंटैक्स का उपयोग सूचकांकों को संरक्षित करने के लिए कर रहा हूं। बेशक यह केवल तालिकाओं की प्रतिलिपि बनाता है। दृश्यों और प्रक्रियाओं की नकल नहीं की जाती है, हालांकि यह उसी तरीके से किया जा सकता है।

बनाएँ तालिका देखें ।


3
यह संदर्भ अखंडता पर विफल हो सकता है क्योंकि निर्भर तालिकाओं को अभी तक कॉपी नहीं किया जा सकता है। शायद यह एक बड़े लेन-देन में काम कर सकता है।
ओन्ड्रेज गाल्बावी

4

सबसे पहले डुप्लिकेट डेटाबेस बनाएँ:

CREATE DATABASE duplicateddb;

सुनिश्चित करें कि अनुमति आदि सभी जगह हैं और:

mysqldump -u admin -p originaldb | mysql -u backup -p password duplicateddb;


1

यह कथन MySQL 5.1.7 में जोड़ा गया था लेकिन खतरनाक पाया गया था और MySQL 5.1.23 में हटा दिया गया था। डेटाबेस निर्देशिका नामों के लिए डेटाबेस के नाम मैपिंग के लिए 5.1 में लागू एन्कोडिंग का उपयोग करने के लिए पूर्व 5.1 डेटाबेस को अपग्रेड करने में सक्षम करने का इरादा था। हालाँकि, इस कथन के उपयोग से डेटाबेस सामग्री नष्ट हो सकती है, यही कारण है कि इसे हटा दिया गया था। पिछले संस्करणों में RENAME DATABASE का उपयोग न करें जिसमें यह मौजूद है।

नए एन्कोडिंग के साथ डेटाबेस नामों को अपग्रेड करने का कार्य करने के लिए, इसके बजाय ALAT DATABASE db_name UPGRADE DATA DIRECTORY NAME का उपयोग करें: http://dev.mysql.com/doc/refman/5.1/en-elter-database.html


1

यदि आप phpmyadmin स्थापित करते हैं तो ऐसा करने का एक सरल तरीका :

अपने डेटाबेस पर जाएं, "ऑपरेशन" टैब चुनें, और आप "कॉपी डेटाबेस" को ब्लॉक कर सकते हैं। इसका उपयोग करें और आप डेटाबेस की प्रतिलिपि बना सकते हैं।


1

जैसा कि ग्रेग के जवाब में बताया गया है , डेटाबेस के बीच डेटा ट्रांसफर करनेmysqldump db_name | mysql new_db_name का मुफ्त, सुरक्षित और आसान तरीका है। हालाँकि, यह वास्तव में धीमा है

यदि आप बैकअप डेटा देख रहे हैं, तो डेटा (इस या अन्य डेटाबेस में) को खोने का जोखिम नहीं उठा सकते हैं, या इसके अलावा अन्य तालिकाओं का उपयोग कर रहे हैं innodb, तो आपको उपयोग करना चाहिए mysqldump

यदि आप विकास के लिए कुछ खोज रहे हैं, तो आपके सभी डेटाबेस कहीं और समर्थित हैं, और mysqlजब सब कुछ गलत हो जाता है, तो आप आसानी से शुद्ध और पुन: स्थापित कर रहे हैं।

मुझे एक अच्छा विकल्प नहीं मिला, इसलिए मैंने इसे स्वयं करने के लिए एक स्क्रिप्ट बनाई। मैंने बहुत खर्च किया पहली बार काम करने के लिए इसे प्राप्त करने में समय और यह ईमानदारी से मुझे इसमें बदलाव करने के लिए थोड़ा परेशान करता है। Innodb डेटाबेस इस तरह से कॉपी और पेस्ट करने के लिए नहीं थे। छोटे बदलाव इसके कारण शानदार तरीके से विफल हो जाते हैं। जब से मैंने कोड को अंतिम रूप दिया, मुझे कोई समस्या नहीं है, लेकिन इसका मतलब यह नहीं है कि आप नहीं करेंगे।

सिस्टम पर परीक्षण किया गया (लेकिन अभी भी विफल हो सकता है):

  • Ubuntu 16.04, डिफ़ॉल्ट mysql, innodb, प्रति तालिका अलग-अलग फाइलें
  • Ubuntu 18.04, डिफ़ॉल्ट mysql, innodb, प्रति तालिका अलग-अलग फाइलें

यह क्या करता है

  1. हो जाता है sudoआप डेटाबेस क्लोन करने के लिए पर्याप्त संग्रहण स्थान विशेषाधिकार और सत्यापन
  2. रूट mysql विशेषाधिकार प्राप्त करता है
  3. वर्तमान गिट शाखा के नाम से एक नया डेटाबेस बनाता है
  4. नए डेटाबेस के लिए क्लोन संरचना
  5. Innodb के लिए रिकवरी मोड में स्विच करता है
  6. नए डेटाबेस में डिफ़ॉल्ट डेटा हटाता है
  7. रुक जाता है mysql
  8. नए डेटाबेस में क्लोन डेटा
  9. Mysql शुरू करता है
  10. नए डेटाबेस में लिंक आयातित डेटा
  11. निर्दोष के लिए वसूली मोड से बाहर स्विच
  12. Mysql को पुनरारंभ करता है
  13. डेटाबेस के लिए mysql उपयोगकर्ता पहुँच देता है
  14. अस्थायी फ़ाइलों को साफ करता है

यह कैसे तुलना करता है mysqldump

3 जीबी डेटाबेस पर, मेरी मशीन पर 40-50 मिनट का उपयोग करके mysqldumpऔर mysqlले जाएगा। इस विधि का उपयोग करते हुए, इस प्रक्रिया में केवल ~ 8 मिनट लगेंगे।

हम इसका उपयोग कैसे करते हैं

हमारे पास हमारे एसक्यूएल परिवर्तन हमारे कोड के साथ सहेजे गए हैं और अपग्रेड प्रक्रिया उत्पादन और विकास दोनों पर स्वचालित है, जिसमें त्रुटियों के होने पर उसे पुनर्स्थापित करने के लिए डेटाबेस का बैकअप बनाने के प्रत्येक सेट के साथ। जब हम डेटाबेस में बदलाव के साथ एक दीर्घकालिक परियोजना पर काम कर रहे थे, तब एक समस्या थी, और एक बग या तीन को ठीक करने के लिए इसके बीच की शाखाओं को बदलना था।

अतीत में, हमने सभी शाखाओं के लिए एक एकल डेटाबेस का उपयोग किया था, और जब भी हम एक नई शाखा में बदलाव के साथ संगत नहीं थे, तो हम डेटाबेस को फिर से बनाना चाहेंगे। और जब हम वापस चले गए, तो हमें फिर से अपग्रेड चलाना होगा।

हमने mysqldumpविभिन्न शाखाओं के लिए डेटाबेस को डुप्लिकेट करने की कोशिश की , लेकिन प्रतीक्षा समय बहुत लंबा था (40-50 मिनट), और हम इस बीच कुछ और नहीं कर सके।

इस समाधान ने डेटाबेस क्लोन समय को 1/5 तक छोटा कर दिया (लंबे लंच के बजाय कॉफी और बाथरूम ब्रेक के बारे में सोचें)।

सामान्य कार्य और उनका समय

असंगत डेटाबेस परिवर्तनों के साथ शाखाओं के बीच स्विच करने पर एकल डेटाबेस पर 50+ मिनट लगते हैं, लेकिन mysqldumpइस कोड के साथ प्रारंभिक सेटअप समय के बाद बिल्कुल भी नहीं । यह कोड केवल ~ 5 गुना तेजी से होता है mysqldump

यहाँ कुछ सामान्य कार्य हैं और मोटे तौर पर प्रत्येक विधि में उन्हें कितना समय लगेगा:

डेटाबेस परिवर्तन के साथ सुविधा शाखा बनाएं और तुरंत मर्ज करें:

  • एकल डेटाबेस: ~ 5 मिनट
  • क्लोन के साथ mysqldump: 50-60 मिनट
  • इस कोड के साथ क्लोन: ~ 18 मिनट

डेटाबेस परिवर्तन के साथ फीचर ब्रांच बनाएं, masterबगफिक्स के लिए स्विच करें, फीचर ब्रांच पर एडिट करें और मर्ज करें:

  • एकल डेटाबेस: ~ 60 मिनट
  • क्लोन के साथ mysqldump: 50-60 मिनट
  • इस कोड के साथ क्लोन: ~ 18 मिनट

डेटाबेस परिवर्तन के साथ फ़ीचर ब्रांच बनाएं, फ़ीचर ब्रांच masterइनबेटविइन पर एडिट करते समय 5 बार बगफिक्स के लिए स्विच करें और मर्ज करें:

  • एकल डेटाबेस: ~ 4 घंटे, 40 मिनट
  • क्लोन के साथ mysqldump: 50-60 मिनट
  • इस कोड के साथ क्लोन: ~ 18 मिनट

कोड

इसका उपयोग तब तक न करें जब तक कि आपने ऊपर की सभी चीज़ों को पढ़ और समझ न लिया हो।

#!/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

यदि सब कुछ सुचारू रूप से चलता है, तो आपको कुछ इस तरह देखना चाहिए:

उदाहरण डेटाबेस के लिए स्क्रिप्ट आउटपुट का स्क्रीनशॉट


0

ग्रेग के जवाब के अलावा , यह सबसे आसान और सबसे तेज़ तरीका है अगर 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

0

यदि आपके पास अपने मूल डेटाबेस में ट्रिगर है, तो आप आयात से पहले प्रतिस्थापन को पाइप करके "ट्रिगर पहले से मौजूद है" त्रुटि से बच सकते हैं:

mysqldump -u olddbuser -p -d olddbname | sed "s/`olddbname`./`newdbname`./" | mysql -u newdbuser -p -D newdbname

-4

मुझे नहीं लगता कि ऐसा करने का कोई तरीका है। जब PHPMyAdmin ऐसा करता है, तो वह DB को डंप करता है और फिर नए नाम के तहत उसे फिर से सम्मिलित करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.