Nhân bản một cơ sở dữ liệu MySQL trên cùng một ví dụ MySql


154

Tôi muốn viết một kịch bản mà các bản sao cơ sở dữ liệu hiện tại của tôi sitedb1để sitedb2trên cơ sở dữ liệu mysql dụ tương tự. Tôi biết tôi có thể chuyển sitedb1 sang tập lệnh sql:

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

và sau đó nhập nó vào sitedb2. Có cách nào dễ dàng hơn mà không bỏ cơ sở dữ liệu đầu tiên vào tệp sql không?


Có thể trùng lặp cơ sở dữ liệu Clone MySQL
bummi

Câu trả lời:


302

Như hướng dẫn nói trong Sao chép cơ sở dữ liệu, bạn có thể chuyển trực tiếp kết xuất vào máy khách mysql:

mysqldump db_name | mysql new_db_name

Nếu bạn đang sử dụng MyISAM, bạn có thể sao chép các tệp, nhưng tôi không khuyến nghị. Đó là một chút tinh ranh.

Tích hợp từ nhiều câu trả lời hay khác

Cả hai mysqldumpmysqllệnh chấp nhận tùy chọn để thiết lập chi tiết kết nối (và nhiều hơn nữa), như:

mysqldump -u <user name> --password=<pwd> <original db> | mysql -u <user name> -p <new db>

Ngoài ra, nếu cơ sở dữ liệu mới chưa tồn tại, bạn phải tạo trước nó (ví dụ: với echo "create database new_db_name" | mysql -u <dbuser> -p).


2
Mặc dù ... nó bỏ qua rất nhiều đĩa IO mặc dù bạn không phải đọc / ghi dữ liệu hai lần
Greg

8
Nếu cơ sở dữ liệu của bạn có kích thước gigabyte, điều này có thể sẽ không giúp bạn kiếm được nhiều tiền. Tôi nghĩ rằng OP đang nhận được là họ không muốn ra bên ngoài bản sao: nó có thể được thực hiện hoàn toàn trong mysql không?
cletus

3
Tôi muốn nói rằng DB càng lớn thì bạn càng kiếm được nhiều tiền ... Không có cách nào để thực hiện điều này trong MySQL afaik (ngoại trừ bằng tay, một bảng / lượt xem tại một thời điểm)
Greg

41
Trước tiên tôi phải tạo new_db bằng cách sử dụng lệnh mysql tiêu chuẩn: "CREATE DATABASE new_db;" và sau đó sử dụng các lệnh này: mysqldump -u root -p old_db | gốc mys -u -p new_db
valentt

4
Điều này không hiệu quả với tôi, nếu tôi phải nhập mật khẩu để bán phá giá và nhập như thế này : mysqldump -uroot -p database1 | mysql -uroot -p database2. Tôi được nhắc cho cả hai pws nhưng chỉ có thể đặt trong một. Lời nhắc trông như thế này : Enter password: Enter password: . Sau khi đưa ra pw đầu tiên, quá trình chờ đợi mãi mãi.
Torsten

66

Sử dụng tiện ích MySQL

Các tiện ích MySQL chứa công cụ tuyệt vời mysqldbcopy, theo mặc định, sao chép một DB bao gồm tất cả các đối tượng liên quan (bảng, chế độ xem, trình kích hoạt, sự kiện, quy trình, chức năng và cấp cơ sở dữ liệu cấp dữ liệu) và dữ liệu từ một máy chủ DB sang cùng hoặc cho một máy chủ khác Máy chủ DB. Có rất nhiều tùy chọn có sẵn để tùy chỉnh những gì thực sự được sao chép.

Vì vậy, để trả lời câu hỏi của OP:

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

1
Điều này làm việc tốt cho tôi, mysqldumpgiải pháp dựa trên đã thất bại.
saji89

1
Trong trường hợp của tôi, tôi đã phải chỉ định cổng như thế này: --source = root: your_password @ localhost: 3307 (nếu không, nó sẽ cung cấp cho tôi lỗi truy cập bị từ chối)
pbz

4
Cần sudo apt-get install mysql-utilities, nhưng điều này là rất gọn gàng. Tôi có thể bỏ mật khẩu và được nhắc nhập mật khẩu không?
ADTC

2
@ADTC Tôi không biết nếu có một cách tích hợp để cho phép mysqldbcopybạn hỏi mật khẩu; ít nhất tôi không thể tìm thấy bất cứ điều gì như thế trong tài liệu. Bạn có thể tự xây dựng chức năng này. Ở Bash có thể trông giống như thế này:mysqldbcopy --source=root:"$(read -sp 'Source password: ' && echo $REPLY)"@localhost --destination=root:"$(read -sp 'Destination password: ' && echo $REPLY)"@localhost sitedb1:sitedb2
Chriki 20/03/2016

1
FYI: Có vẻ như lệnh của Chriki hoạt động hoàn hảo. Tôi chỉ phải thêm --forcevào mysqldbcopylệnh vì tôi đã tạo cơ sở dữ liệu đích. Cảm ơn!
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
Nó làm gì thêm vào câu trả lời được chấp nhận? Tương tự, nhưng bạn thêm một số khác biệt, thêm một số nhận xét để hiểu rõ hơn
Yaroslav

Đây phải là câu trả lời được chấp nhận, vì nó sẽ tạo ra cơ sở dữ liệu, cũng tốt cho auth. câu trả lời được chấp nhận hiện tại sẽ cho bạn biết quyền truy cập bị từ chối, sau đó bảng không tồn tại.
Rami Dabain

14

Bạn cần chạy lệnh từ terminal / dấu nhắc lệnh.

mysqldump -u <user name> -p <pwd> <original db> | mysql -u <user name> <pwd> <new db>

ví dụ: mysqldump -u root test_db1 | mysql -u root test_db2

Điều này sao chép test_db1 sang test_db2 và cấp quyền truy cập vào 'root' @ 'localhost'


Tôi thích câu trả lời này, nó rõ ràng. Tuy nhiên, đối với tôi yêu cầu mysql -p trước khi nhập mật khẩu.
lwitzel

1
Làm thế nào chúng ta cũng có thể sao chép các chức năng, sự kiện, vv được tạo trong cơ sở dữ liệu gốc? Điều này trông chỉ sao chép bảng.
Dogan Askan

12

Cách tốt nhất và dễ dàng là nhập các lệnh này trong thiết bị đầu cuối của bạn và đặt quyền cho người dùng root. Làm việc cho tôi ..!

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

1
Câu hỏi nêu rõ rằng phương thức xuất / nhập đã được biết.
lav

3
Đây là cách tốt nhất để làm điều đó. Cũng hoạt động với cơ sở dữ liệu lớn, trong khi phiên bản đường ống mysqldump -u <user> -p <pwd> db_name | mysql -u <user> -p <pwd> new_db_namecó thể có vấn đề với cơ sở dữ liệu lớn.
Alex

10

Bạn có thể sử dụng (trong mã giả):

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

Lý do tôi không sử dụng cú pháp CREATE TABLE ... CHỌN ... là để bảo toàn các chỉ mục. Tất nhiên điều này chỉ sao chép bảng. Lượt xem và thủ tục không được sao chép, mặc dù nó có thể được thực hiện theo cách tương tự.

Xem TẠO BẢNG .


3
Điều này có thể thất bại về tính toàn vẹn tham chiếu vì các bảng phụ thuộc chưa thể được sao chép. Có lẽ nó có thể làm việc trong một giao dịch lớn.
Ondrej Galbavý

4

Đầu tiên tạo cơ sở dữ liệu trùng lặp:

CREATE DATABASE duplicateddb;

Hãy chắc chắn rằng các quyền vv đều được đặt đúng chỗ và:

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

2

Bạn có thể làm một cái gì đó như sau:

mysqldump -u[username] -p[password] database_name_for_clone 
 | mysql -u[username] -p[password] new_database_name

1

Tuyên bố này đã được thêm vào trong MySQL 5.1.7 nhưng được phát hiện là nguy hiểm và đã bị xóa trong MySQL 5.1.23. Nó được dự định cho phép nâng cấp cơ sở dữ liệu trước 5.1 để sử dụng mã hóa được triển khai trong 5.1 để ánh xạ tên cơ sở dữ liệu thành tên thư mục cơ sở dữ liệu. Tuy nhiên, việc sử dụng câu lệnh này có thể dẫn đến mất nội dung cơ sở dữ liệu, đó là lý do tại sao nó bị xóa. Không sử dụng RENAME DATABASE trong các phiên bản trước đó có mặt.

Để thực hiện nhiệm vụ nâng cấp tên cơ sở dữ liệu bằng mã hóa mới, hãy sử dụng ALTER DATABASE db_name UPGRADE DATA DIRECTORY NAME thay thế: http://dev.mysql.com/doc/refman/5.1/en/alter-database.html


1

Một cách đơn giản để làm như vậy nếu bạn đã cài đặt phpmyadmin :

Chuyển đến cơ sở dữ liệu của bạn, chọn tab "hoạt động" và bạn có thể thấy khối "sao chép cơ sở dữ liệu vào". Sử dụng nó và bạn có thể sao chép cơ sở dữ liệu.


1

Như đã đề cập trong câu trả lời của Greg , mysqldump db_name | mysql new_db_namelà cách miễn phí, an toàn và dễ dàng để chuyển dữ liệu giữa các cơ sở dữ liệu. Tuy nhiên, nó cũng rất chậm .

Nếu bạn đang tìm cách sao lưu dữ liệu, không thể để mất dữ liệu (trong cơ sở dữ liệu này hoặc cơ sở dữ liệu khác) hoặc đang sử dụng các bảng khác innodb, thì bạn nên sử dụng mysqldump.

Nếu bạn đang tìm kiếm thứ gì đó để phát triển, có tất cả các cơ sở dữ liệu của bạn được sao lưu ở nơi khác và thoải mái thanh lọc và cài đặt lại mysql(có thể là thủ công) khi mọi thứ không ổn, thì tôi có thể có giải pháp cho bạn.

Tôi không thể tìm thấy một sự thay thế tốt, vì vậy tôi đã xây dựng một kịch bản để tự làm điều đó. Tôi đã dành rất nhiều thời gian để làm việc này lần đầu tiên và nó thực sự làm tôi sợ một chút để thay đổi nó ngay bây giờ. Cơ sở dữ liệu Innodb không có nghĩa là sao chép và dán như thế này. Những thay đổi nhỏ khiến điều này thất bại theo những cách tuyệt vời. Tôi đã không gặp vấn đề gì kể từ khi tôi hoàn tất mã, nhưng điều đó không có nghĩa là bạn sẽ không.

Các hệ thống được thử nghiệm trên (nhưng vẫn có thể thất bại):

  • Ubuntu 16.04, mysql mặc định, innodb, các tệp riêng biệt trên mỗi bảng
  • Ubuntu 18.04, mysql mặc định, innodb, các tệp riêng biệt trên mỗi bảng

Những gì nó làm

  1. Nhận sudođặc quyền và xác minh bạn có đủ dung lượng lưu trữ để sao chép cơ sở dữ liệu
  2. Được quyền root mysql
  3. Tạo một cơ sở dữ liệu mới được đặt tên theo nhánh git hiện tại
  4. Cấu trúc nhân bản vào cơ sở dữ liệu mới
  5. Chuyển sang chế độ phục hồi cho innodb
  6. Xóa dữ liệu mặc định trong cơ sở dữ liệu mới
  7. Dừng mysql
  8. Nhân bản dữ liệu vào cơ sở dữ liệu mới
  9. Bắt đầu mysql
  10. Liên kết dữ liệu đã nhập trong cơ sở dữ liệu mới
  11. Chuyển ra khỏi chế độ phục hồi cho innodb
  12. Khởi động lại mysql
  13. Cung cấp cho người dùng mysql quyền truy cập vào cơ sở dữ liệu
  14. Dọn dẹp tập tin tạm thời

Làm thế nào nó so sánh với mysqldump

Trên cơ sở dữ liệu 3gb, sử dụng mysqldumpmysqlsẽ mất 40-50 phút trên máy của tôi. Sử dụng phương pháp này, quá trình tương tự sẽ chỉ mất ~ 8 phút.

Chúng ta sử dụng nó như thế nào

Chúng tôi có các thay đổi SQL được lưu cùng với mã của chúng tôi và quá trình nâng cấp được tự động hóa trên cả sản xuất và phát triển, với mỗi bộ thay đổi tạo bản sao lưu cơ sở dữ liệu để khôi phục nếu có lỗi. Một vấn đề chúng tôi gặp phải là khi chúng tôi đang thực hiện một dự án dài hạn với các thay đổi cơ sở dữ liệu và phải chuyển các nhánh ở giữa nó để sửa một hoặc ba lỗi.

Trước đây, chúng tôi đã sử dụng một cơ sở dữ liệu duy nhất cho tất cả các chi nhánh và sẽ phải xây dựng lại cơ sở dữ liệu bất cứ khi nào chúng tôi chuyển sang một chi nhánh không tương thích với các thay đổi cơ sở dữ liệu mới. Và khi chúng tôi quay trở lại, chúng tôi sẽ phải chạy lại các bản nâng cấp.

Chúng tôi đã cố gắng mysqldumpsao chép cơ sở dữ liệu cho các chi nhánh khác nhau, nhưng thời gian chờ đợi quá dài (40-50 phút) và chúng tôi không thể làm gì khác trong lúc này.

Giải pháp này rút ngắn thời gian sao chép cơ sở dữ liệu xuống còn 1/5 thời gian (nghĩ rằng nghỉ giải lao và cà phê thay vì một bữa trưa dài).

Nhiệm vụ chung và thời gian của họ

Chuyển đổi giữa các nhánh với thay đổi cơ sở dữ liệu không tương thích mất hơn 50 phút trên một cơ sở dữ liệu, nhưng không có thời gian nào sau thời gian thiết lập ban đầu với mysqldump hoặc mã này. Mã này chỉ xảy ra nhanh hơn ~ 5 lần so vớimysqldump .

Dưới đây là một số tác vụ phổ biến và khoảng thời gian chúng sẽ sử dụng trong mỗi phương thức:

Tạo nhánh tính năng với các thay đổi cơ sở dữ liệu và hợp nhất ngay lập tức:

  • Cơ sở dữ liệu duy nhất: ~ 5 phút
  • Nhân bản với mysqldump: 50-60 phút
  • Sao chép với mã này: ~ 18 phút

Tạo nhánh tính năng với các thay đổi cơ sở dữ liệu, chuyển sang tìm masterlỗi, thực hiện chỉnh sửa trên nhánh tính năng và hợp nhất:

  • Cơ sở dữ liệu duy nhất: ~ 60 phút
  • Nhân bản với mysqldump: 50-60 phút
  • Sao chép với mã này: ~ 18 phút

Tạo nhánh tính năng với các thay đổi cơ sở dữ liệu, chuyển sang sửa masterlỗi 5 lần trong khi thực hiện các chỉnh sửa trên nhánh tính năng ở giữa và hợp nhất:

  • Cơ sở dữ liệu duy nhất: ~ 4 giờ, 40 phút
  • Nhân bản với mysqldump: 50-60 phút
  • Sao chép với mã này: ~ 18 phút

Mật mã

Không sử dụng điều này trừ khi bạn đã đọc và hiểu mọi thứ ở trên.

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

Nếu mọi thứ diễn ra suôn sẻ, bạn sẽ thấy một cái gì đó như:

Ảnh chụp màn hình của đầu ra tập lệnh cho cơ sở dữ liệu ví dụ


0

Ngoài câu trả lời của Greg , đây là cách dễ nhất và nhanh nhất nếu new_db_namechưa tồn tại:

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

Nếu bạn có các kích hoạt trong cơ sở dữ liệu ban đầu của mình, bạn có thể tránh lỗi "Kích hoạt đã tồn tại" bằng cách thay thế trước khi nhập:

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

-4

Tôi không nghĩ có một phương pháp để làm điều này. Khi PHPMyAdmin thực hiện điều này, nó kết xuất DB sau đó chèn lại nó dưới tên mới.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.