คัดลอก / ทำซ้ำฐานข้อมูลโดยไม่ใช้ mysqldump


427

หากไม่มีการเข้าถึงเซิร์ฟเวอร์ในพื้นที่จะมีวิธีใดที่จะทำซ้ำ / โคลนฐานข้อมูล MySQL (ที่มีเนื้อหาและไม่มีเนื้อหา) ไปยังที่อื่นโดยไม่ใช้mysqldumpหรือไม่?

ฉันกำลังใช้ MySQL 4.0


12
มีอะไรผิดปกติกับmysqldump?
Michael Mior

48
ตรวจสอบให้แน่ใจว่าคุณไม่ได้ทำสิ่งนี้: CREATE TABLE t2 SELECT * FROM t1;เนื่องจากคุณสูญเสียข้อมูลดัชนีสิ่งพิเศษใด ๆ เช่น auto_increment ฯลฯ .. google หลาย ๆ อันสำหรับตารางคัดลอกนี้จะนำคุณไปสู่การทำสิ่งนี้และจะได้ผลลัพธ์ที่ไม่ต้องการ .
John Hunt

59
คำถามปิดหัวข้อรับ 92 upvotes และ 37 รายการโปรด ยกนิ้วให้สำหรับคำถามปิดหัวข้อดังกล่าว แนวทางที่ล้าสมัย
pal4life

25
100% ยอมรับว่า "ปิดเป็นหัวข้อปิด" ผิดและควรปรับปรุงกิลเดลีน - จำเป็นต้องใช้ความอดทนมากขึ้น - ดังนั้นมุ่งไปในทิศทางที่ผิด เห็นได้ชัดว่า @ จะไม่ถูกปิดเครื่องหมายอย่างสมบูรณ์และควรลบสิทธิ์ผู้ดูแลของเขาออก - คำถามเดียวนี้พิสูจน์ได้ว่าเพียงพอ
stolsvik

10
ปิดหัวข้อปิดผิด 100% นี่เป็นคำถามที่แน่นอนที่ฉันมีและมีคำตอบทางเทคนิคที่กำหนดไว้อย่างดีซึ่งไม่เกี่ยวข้องกับความคิดเห็นเพียงอย่างเดียว ฉันคิดว่าผู้ดำเนินรายการต้องทำการค้นหาคำเช่น "ดีที่สุด" เพื่อค้นหาคำถามที่จะปิด
Sam Goldberg

คำตอบ:


686

ฉันสามารถเห็นคุณบอกว่าคุณไม่ต้องการใช้mysqldumpแต่ฉันมาถึงหน้านี้ในขณะที่มองหาวิธีการแก้ปัญหาที่คล้ายกันและคนอื่น ๆ อาจพบว่ามันเป็นอย่างดี โดยที่ในใจนี่เป็นวิธีง่าย ๆ ในการทำซ้ำฐานข้อมูลจากบรรทัดคำสั่งของเซิร์ฟเวอร์ windows:

  1. สร้างฐานข้อมูลเป้าหมายโดยใช้ MySQLAdmin หรือวิธีการที่คุณต้องการ ในตัวอย่างนี้db2คือฐานข้อมูลเป้าหมายโดยที่ฐานข้อมูลต้นฉบับdb1จะถูกคัดลอก
  2. ดำเนินการคำสั่งต่อไปนี้บนบรรทัดคำสั่ง:

mysqldump -h [server] -u [user] -p[password] db1 | mysql -h [server] -u [user] -p[password] db2

หมายเหตุ: ไม่มีที่ว่างระหว่าง-pและ[password]


108
กรณีต่อmysqldumpนั้นจะต้องมีวิธีที่รวดเร็วกว่าจากนั้นจัดลำดับข้อมูลลงในคิวรีส่งสัญญาณเคียวรีภายนอกกระบวนการและผ่าน tty กลับไปเป็นกระบวนการเดียวกันแน่นอนการแยกเคียวรีและเรียกใช้งานเป็นคำสั่ง ที่ฟังดูน่ากลัวที่ไม่มีประสิทธิภาพและไม่จำเป็น เราไม่ได้พูดถึงการข้ามระหว่าง MySQL หลักหรือเปลี่ยนเครื่องมือเก็บข้อมูล มันน่าตกใจที่ไม่มีการถ่ายโอนระหว่างไบนารีที่มีประสิทธิภาพ
Toddius Zho

42
หากคุณไม่ต้องการบันทึกรหัสผ่านธรรมดาในประวัติเทอร์มินัลของคุณคุณจะต้องแยกคำสั่ง: mysqldump -h [server] -u [user] -p db1 > db1, mysql -h [server] -u [user] -p db2 < db1 มิฉะนั้นรหัสผ่านจะแจ้งให้มันสับสนอย่างน้อยสำหรับฉันเมื่อใช้ผงสำหรับอุดรู
kapex

5
การใช้ mysqldump และ mysql จาก bash นั้นง่ายกว่ามากหากคุณตั้งค่าไฟล์. my.cnf ของคุณเพื่อจัดเก็บไฟล์ผู้ใช้ / โฮสต์ / รหัสผ่านของคุณ
ErichBSchulz

4
mysqldump -u root -p -v db1 | mysql -u root -p db2และป้อนสองครั้ง
hlcs

6
พระเจ้าโปรดใครบางคนสามารถอธิบายได้ว่าทำไมคำถามที่ระบุว่า "ไม่มี mysqldump" เป็นคำตอบแรกที่ใช้ mysqldump? ด้วยคะแนน 6x มากกว่าคะแนนที่ถูกต้อง ? c'mon, SO ...
igorsantos07

135

คุณสามารถทำสำเนาตารางโดยไม่มีข้อมูลได้ด้วยการเรียกใช้:

CREATE TABLE x LIKE y;

(ดูMySQL สร้างเอกสารตาราง )

คุณสามารถเขียนสคริปต์ที่ใช้เอาต์พุตจากSHOW TABLESฐานข้อมูลหนึ่งและคัดลอกสคีมาไปยังอีก คุณควรอ้างอิงชื่อสคีมา + ตารางเช่น:

CREATE TABLE x LIKE other_db.y;

เท่าที่ข้อมูลไปคุณสามารถทำได้ใน MySQL แต่ไม่จำเป็นต้องเร็ว หลังจากที่คุณสร้างการอ้างอิงคุณสามารถเรียกใช้สิ่งต่อไปนี้เพื่อคัดลอกข้อมูล:

INSERT INTO x SELECT * FROM other_db.y;

หากคุณใช้ MyISAM คุณควรทำการคัดลอกไฟล์ตาราง มันจะเร็วขึ้นมาก คุณควรจะสามารถจะทำเช่นเดียวกันถ้าคุณกำลังใช้ INNODB กับพื้นที่ตารางต่อโต๊ะ

หากคุณจบลงด้วยการให้INSERT INTO SELECTแน่ใจว่าได้ปิดดัชนีชั่วคราวด้วยALTER TABLE x DISABLE KEYS!

แก้ไข Maatkitยังมีสคริปต์บางอย่างที่อาจเป็นประโยชน์สำหรับการซิงค์ข้อมูล อาจไม่เร็วกว่านี้ แต่คุณอาจเรียกใช้สคริปต์การซิงค์กับข้อมูลสดโดยไม่ต้องล็อกมาก


1
ใช้งานกับตารางที่ซ้ำกันได้หรือไม่ เนื่องจากฉันเห็นคำสั่งคือสร้างตาราง
GusDeCooL

4
CREATE TABLE ... SELECTคุณสามารถทำได้
eggyal

3
ฉันพยายามคัดลอกไฟล์ตารางของฐานข้อมูล MyISAM หนึ่งครั้ง แต่นั่นก็แค่สร้างความเสียหายให้กับฐานข้อมูลใหม่ อาจเป็นไปได้ว่าฉันไม่ดี แต่มันก็ไม่ได้เป็นการดำเนินการที่น่ารำคาญอย่างที่บางคนบอกว่ามันเป็น
Johan Fredrik Varen

2
นี่เป็นกลลวงที่ดีและฉันเป็นแฟน แต่สิ่งสำคัญที่ควรทราบ: นี่ไม่ได้มีข้อ จำกัด กุญแจต่างประเทศใด ๆ (แม้แต่ตัวที่อยู่นอกสคีมาที่ถูกคัดลอก) ต่อเอกสาร MySQL
abigperson

59

หากคุณใช้ Linux คุณสามารถใช้สคริปต์ทุบตีนี้: (มันอาจต้องมีการล้างโค้ดเพิ่มเติม แต่ใช้งานได้ ... และมันก็เร็วกว่า mysqldump | mysql)

#!/bin/bash

DBUSER=user
DBPASSWORD=pwd
DBSNAME=sourceDb
DBNAME=destinationDb
DBSERVER=db.example.com

fCreateTable=""
fInsertData=""
echo "Copying database ... (may take a while ...)"
DBCONN="-h ${DBSERVER} -u ${DBUSER} --password=${DBPASSWORD}"
echo "DROP DATABASE IF EXISTS ${DBNAME}" | mysql ${DBCONN}
echo "CREATE DATABASE ${DBNAME}" | mysql ${DBCONN}
for TABLE in `echo "SHOW TABLES" | mysql $DBCONN $DBSNAME | tail -n +2`; do
        createTable=`echo "SHOW CREATE TABLE ${TABLE}"|mysql -B -r $DBCONN $DBSNAME|tail -n +2|cut -f 2-`
        fCreateTable="${fCreateTable} ; ${createTable}"
        insertData="INSERT INTO ${DBNAME}.${TABLE} SELECT * FROM ${DBSNAME}.${TABLE}"
        fInsertData="${fInsertData} ; ${insertData}"
done;
echo "$fCreateTable ; $fInsertData" | mysql $DBCONN $DBNAME

7
หากคุณกำลังใช้สคริปต์ด้านบนกับตาราง InnoDB และมีคีย์ต่างประเทศให้เปลี่ยนบรรทัดสุดท้ายเป็นต่อไปนี้:echo "set foreign_key_checks = 0; $fCreateTable ; $fInsertData ; set foreign_key_checks = 1;" | mysql $DBCONN $DBNAME
pegli

สิ่งนี้ยังคัดลอกข้อมูลข้อ จำกัด และคุณสมบัติอื่น ๆ ของตารางหรือไม่
Lucas Moeskops

1
ดูเหมือนว่าเพราะเขาใช้คำสั่ง "SHOW CREATE TABLE" ซึ่งสร้าง CREATE TABLE พร้อมคุณสมบัติทั้งหมดของต้นฉบับ
Danita

1
หากคุณพบปัญหา @zirael อธิบายว่าอาจเป็นเพราะสคริปต์ไม่สามารถคัดลอกมุมมองได้ คุณสามารถละเว้นมุมมองจากการคัดลอกโดยการเปลี่ยนSHOW TABLESสายไปและการเพิ่มSHOW FULL TABLES WHERE Table_Type = 'BASE TABLE' | cut -f 1สายสมบูรณ์ควรมีลักษณะเช่นนี้ แต่แทนที่ backticks สองครั้งด้วย backticks เดียว: for TABLE in ``echo "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'" | mysql $DBCONN $DBSNAME | tail -n +2 | cut -f 1``; do
รหัสผู้บัญชาการ

1
ฉันได้ทำความสะอาดสคริปต์นี้โดย @jozjan และใช้ความคิดเห็นบางส่วนเกี่ยวกับกุญแจจากต่างประเทศและกุญแจอื่น ๆ เพื่อสร้างรุ่นนี้ใน GIST gist.github.com/christopher-hopper/8431737
Christopher

11

ใน PHP:

function cloneDatabase($dbName, $newDbName){
    global $admin;
    $db_check = @mysql_select_db ( $dbName );
    $getTables  =   $admin->query("SHOW TABLES");   
    $tables =   array();
    while($row = mysql_fetch_row($getTables)){
        $tables[]   =   $row[0];
    }
    $createTable    =   mysql_query("CREATE DATABASE `$newDbName` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;") or die(mysql_error());
    foreach($tables as $cTable){
        $db_check   =   @mysql_select_db ( $newDbName );
        $create     =   $admin->query("CREATE TABLE $cTable LIKE ".$dbName.".".$cTable);
        if(!$create) {
            $error  =   true;
        }
        $insert     =   $admin->query("INSERT INTO $cTable SELECT * FROM ".$dbName.".".$cTable);
    }
    return !isset($error);
}


// usage
$clone  = cloneDatabase('dbname','newdbname');  // first: toCopy, second: new database

หากคุณกำลังทำงานกับเครื่อง windows จากนั้นกรุณาใช้สิ่งนี้แทนการค้นหาวิธีที่ยาวเพื่อเรียกใช้คำสั่ง
Parixit

สคริปต์นี้ไม่นับจำนวนการดู
sd1sd1

4

โปรดทราบว่ามีคำสั่ง mysqldbcopy เป็นส่วนหนึ่งของการเพิ่มโปรแกรมอรรถประโยชน์ mysql .... https://dev.mysql.com/doc/mysql-utilities/1.5/en/utils-task-clone-db.html


แต่มันต้องติดตั้งแพคเกจเพิ่มเติม:apt install mysql-utilities
Joel G Mathew

2
แต่ไม่มีข้อ จำกัด ที่บอกว่าเป็นไปไม่ได้ .... และมันเป็นสิ่งที่ติดตั้งทั่วไป (แต่เป็นทางเลือกตามที่คุณพูด) หากยังไม่ได้ติดตั้งหลายคนจะพบว่าการติดตั้งแพคเกจนั้นง่ายกว่าการติดตั้งและใช้สคริปต์ Bash 60 บรรทัด และอื่น ๆ ....
furicle

โพสต์ของคุณอาจถูกโหวตเพราะคุณไม่ได้รวมข้อมูลอื่นใดนอกเหนือจากลิงค์ คำตอบควรจะครอบคลุมมากขึ้น
Joel G Mathew

1

ฉันไม่รู้จริงๆว่าคุณหมายถึงอะไรโดย "การเข้าถึงในพื้นที่" แต่สำหรับการแก้ปัญหาที่คุณต้องการเพื่อให้สามารถเข้าถึงผ่าน SSH เซิร์ฟเวอร์เพื่อคัดลอกไฟล์ที่เป็นฐานข้อมูลจะถูกเก็บไว้

ฉันไม่สามารถใช้ mysqldump ได้เพราะฐานข้อมูลของฉันมีขนาดใหญ่ (7Go, mysqldump ล้มเหลว) หากรุ่นของฐานข้อมูล mysql 2 แตกต่างกันมากเกินไปอาจไม่ทำงานคุณสามารถตรวจสอบรุ่น mysql ของคุณโดยใช้ mysql -V

1) คัดลอกข้อมูลจากเซิร์ฟเวอร์ระยะไกลของคุณไปยังเครื่องคอมพิวเตอร์ของคุณ (vps คือนามแฝงไปยังเซิร์ฟเวอร์ระยะไกลของคุณสามารถแทนที่ด้วย root@1.2.3.4)

ssh vps:/etc/init.d/mysql stop
scp -rC vps:/var/lib/mysql/ /tmp/var_lib_mysql
ssh vps:/etc/init.d/apache2 start

2) นำเข้าข้อมูลที่คัดลอกบนเครื่องคอมพิวเตอร์ของคุณ

/etc/init.d/mysql stop
sudo chown -R mysql:mysql /tmp/var_lib_mysql
sudo nano /etc/mysql/my.cnf
-> [mysqld]
-> datadir=/tmp/var_lib_mysql
/etc/init.d/mysql start

หากคุณมีรุ่นอื่นคุณอาจต้องเรียกใช้

/etc/init.d/mysql stop
mysql_upgrade -u root -pPASSWORD --force #that step took almost 1hrs
/etc/init.d/mysql start

นี่เป็นวิธีที่มีประสิทธิภาพที่สุดในการทำ แต่ฉันคิดว่า "โดยไม่ต้องเข้าถึงเซิร์ฟเวอร์" หมายความว่าเราไม่สามารถเข้าถึงระบบได้ น่าจะเป็นโฮสติ้งที่ใช้ร่วมกัน? ดังนั้นนี่ไม่ใช่คำตอบ
Valerio Bozz

1

วิธีแก้ไขปัญหาก่อนหน้าทั้งหมดได้มาถึงจุดอย่างไรก็ตามพวกเขาก็ไม่ได้คัดลอกทุกอย่าง ฉันสร้างฟังก์ชั่น PHP (แม้ว่าจะค่อนข้างยาว) ซึ่งคัดลอกทุกอย่างรวมถึงตารางคีย์ต่างประเทศข้อมูลมุมมองโพรซีเดอร์ฟังก์ชันทริกเกอร์และเหตุการณ์ต่างๆ นี่คือรหัส:

/* This function takes the database connection, an existing database, and the new database and duplicates everything in the new database. */
function copyDatabase($c, $oldDB, $newDB) {

    // creates the schema if it does not exist
    $schema = "CREATE SCHEMA IF NOT EXISTS {$newDB};";
    mysqli_query($c, $schema);

    // selects the new schema
    mysqli_select_db($c, $newDB);

    // gets all tables in the old schema
    $tables = "SELECT table_name
               FROM information_schema.tables
               WHERE table_schema = '{$oldDB}'
               AND table_type = 'BASE TABLE'";
    $results = mysqli_query($c, $tables);

    // checks if any tables were returned and recreates them in the new schema, adds the foreign keys, and inserts the associated data
    if (mysqli_num_rows($results) > 0) {

        // recreates all tables first
        while ($row = mysqli_fetch_array($results)) {
            $table = "CREATE TABLE {$newDB}.{$row[0]} LIKE {$oldDB}.{$row[0]}";
            mysqli_query($c, $table);
        }

        // resets the results to loop through again
        mysqli_data_seek($results, 0);

        // loops through each table to add foreign key and insert data
        while ($row = mysqli_fetch_array($results)) {

            // inserts the data into each table
            $data = "INSERT IGNORE INTO {$newDB}.{$row[0]} SELECT * FROM {$oldDB}.{$row[0]}";
            mysqli_query($c, $data);

            // gets all foreign keys for a particular table in the old schema
            $fks = "SELECT constraint_name, column_name, table_name, referenced_table_name, referenced_column_name
                    FROM information_schema.key_column_usage
                    WHERE referenced_table_name IS NOT NULL
                    AND table_schema = '{$oldDB}'
                    AND table_name = '{$row[0]}'";
            $fkResults = mysqli_query($c, $fks);

            // checks if any foreign keys were returned and recreates them in the new schema
            // Note: ON UPDATE and ON DELETE are not pulled from the original so you would have to change this to your liking
            if (mysqli_num_rows($fkResults) > 0) {
                while ($fkRow = mysqli_fetch_array($fkResults)) {
                    $fkQuery = "ALTER TABLE {$newDB}.{$row[0]}                              
                                ADD CONSTRAINT {$fkRow[0]}
                                FOREIGN KEY ({$fkRow[1]}) REFERENCES {$newDB}.{$fkRow[3]}({$fkRow[1]})
                                ON UPDATE CASCADE
                                ON DELETE CASCADE;";
                    mysqli_query($c, $fkQuery);
                }
            }
        }   
    }

    // gets all views in the old schema
    $views = "SHOW FULL TABLES IN {$oldDB} WHERE table_type LIKE 'VIEW'";                
    $results = mysqli_query($c, $views);

    // checks if any views were returned and recreates them in the new schema
    if (mysqli_num_rows($results) > 0) {
        while ($row = mysqli_fetch_array($results)) {
            $view = "SHOW CREATE VIEW {$oldDB}.{$row[0]}";
            $viewResults = mysqli_query($c, $view);
            $viewRow = mysqli_fetch_array($viewResults);
            mysqli_query($c, preg_replace("/CREATE(.*?)VIEW/", "CREATE VIEW", str_replace($oldDB, $newDB, $viewRow[1])));
        }
    }

    // gets all triggers in the old schema
    $triggers = "SELECT trigger_name, action_timing, event_manipulation, event_object_table, created
                 FROM information_schema.triggers
                 WHERE trigger_schema = '{$oldDB}'";                 
    $results = mysqli_query($c, $triggers);

    // checks if any triggers were returned and recreates them in the new schema
    if (mysqli_num_rows($results) > 0) {
        while ($row = mysqli_fetch_array($results)) {
            $trigger = "SHOW CREATE TRIGGER {$oldDB}.{$row[0]}";
            $triggerResults = mysqli_query($c, $trigger);
            $triggerRow = mysqli_fetch_array($triggerResults);
            mysqli_query($c, str_replace($oldDB, $newDB, $triggerRow[2]));
        }
    }

    // gets all procedures in the old schema
    $procedures = "SHOW PROCEDURE STATUS WHERE db = '{$oldDB}'";
    $results = mysqli_query($c, $procedures);

    // checks if any procedures were returned and recreates them in the new schema
    if (mysqli_num_rows($results) > 0) {
        while ($row = mysqli_fetch_array($results)) {
            $procedure = "SHOW CREATE PROCEDURE {$oldDB}.{$row[1]}";
            $procedureResults = mysqli_query($c, $procedure);
            $procedureRow = mysqli_fetch_array($procedureResults);
            mysqli_query($c, str_replace($oldDB, $newDB, $procedureRow[2]));
        }
    }

    // gets all functions in the old schema
    $functions = "SHOW FUNCTION STATUS WHERE db = '{$oldDB}'";
    $results = mysqli_query($c, $functions);

    // checks if any functions were returned and recreates them in the new schema
    if (mysqli_num_rows($results) > 0) {
        while ($row = mysqli_fetch_array($results)) {
            $function = "SHOW CREATE FUNCTION {$oldDB}.{$row[1]}";
            $functionResults = mysqli_query($c, $function);
            $functionRow = mysqli_fetch_array($functionResults);
            mysqli_query($c, str_replace($oldDB, $newDB, $functionRow[2]));
        }
    }

    // selects the old schema (a must for copying events)
    mysqli_select_db($c, $oldDB);

    // gets all events in the old schema
    $query = "SHOW EVENTS
              WHERE db = '{$oldDB}';";
    $results = mysqli_query($c, $query);

    // selects the new schema again
    mysqli_select_db($c, $newDB);

    // checks if any events were returned and recreates them in the new schema
    if (mysqli_num_rows($results) > 0) {
        while ($row = mysqli_fetch_array($results)) {
            $event = "SHOW CREATE EVENT {$oldDB}.{$row[1]}";
            $eventResults = mysqli_query($c, $event);
            $eventRow = mysqli_fetch_array($eventResults);
            mysqli_query($c, str_replace($oldDB, $newDB, $eventRow[3]));
        }
    }
}

ลดลงเนื่องจากคำถามไม่ใช่ "ไม่ใช้ mysqldump" แต่ "ใช้วิธีที่ดีกว่า mysqldump" สิ่งนี้ยิ่งแย่ลงmysqldumpในแง่ของประสิทธิภาพ
Valerio Bozz

1

อันที่จริงฉันต้องการบรรลุว่าใน PHP แต่ไม่มีคำตอบที่นี่มีประโยชน์มากดังนั้นนี่คือโซลูชันตรงไปตรงมาของฉัน - โดยใช้ MySQLi:

// Database variables

$DB_HOST = 'localhost';
$DB_USER = 'root';
$DB_PASS = '1234';

$DB_SRC = 'existing_db';
$DB_DST = 'newly_created_db';



// MYSQL Connect

$mysqli = new mysqli( $DB_HOST, $DB_USER, $DB_PASS ) or die( $mysqli->error );



// Create destination database

$mysqli->query( "CREATE DATABASE $DB_DST" ) or die( $mysqli->error );



// Iterate through tables of source database

$tables = $mysqli->query( "SHOW TABLES FROM $DB_SRC" ) or die( $mysqli->error );

while( $table = $tables->fetch_array() ): $TABLE = $table[0];


    // Copy table and contents in destination database

    $mysqli->query( "CREATE TABLE $DB_DST.$TABLE LIKE $DB_SRC.$TABLE" ) or die( $mysqli->error );
    $mysqli->query( "INSERT INTO $DB_DST.$TABLE SELECT * FROM $DB_SRC.$TABLE" ) or die( $mysqli->error );


endwhile;

ฉันไม่แน่ใจว่า tihis สร้าง 1: 1 clone แต่ดูเหมือนว่าฐานข้อมูลอย่างง่ายอาจเพียงพอ
beppe9000

ฉันใช้สิ่งนั้นเพื่อสร้างการติดตั้ง WordPress ที่รวดเร็วบนเซิร์ฟเวอร์การพัฒนาของฉัน ส่วนนี้จับคู่กับงานประจำอื่นที่ซ้ำกันและปรับการติดตั้งแหล่งที่มาให้เป็นโครงการใหม่ เพราะมันใช้งานได้ดี… แต่ฐานข้อมูลเวิร์ดเพรสที่ว่างเปล่าไม่ซับซ้อนดังนั้นฉันจึงไม่สามารถใช้คำสั่งสำหรับกรณีการใช้งานที่ยาวนานขึ้นได้อีก
GDY

0

วิธีที่ดีที่สุดในการโคลนตารางฐานข้อมูลโดยไม่มี mysqldump:

  1. สร้างฐานข้อมูลใหม่
  2. สร้างแบบสอบถามโคลนด้วยแบบสอบถาม:

    SET @NewSchema = 'your_new_db';
    SET @OldSchema = 'your_exists_db';
    SELECT CONCAT('CREATE TABLE ',@NewSchema,'.',table_name, ' LIKE ', TABLE_SCHEMA ,'.',table_name,';INSERT INTO ',@NewSchema,'.',table_name,' SELECT * FROM ', TABLE_SCHEMA ,'.',table_name,';') 
    FROM information_schema.TABLES where TABLE_SCHEMA = @OldSchema AND TABLE_TYPE != 'VIEW';
  3. เรียกใช้เอาต์พุตนั้น!

แต่ทราบสคริปต์ข้างต้นเป็นเพียงตารางโคลนอย่างรวดเร็ว - ไม่ใช่มุมมองทริกเกอร์และฟังก์ชั่นผู้ใช้: คุณสามารถรับโครงสร้างได้อย่างรวดเร็วจากmysqldump --no-data --triggers -uroot -ppasswordนั้นใช้โคลนเพื่อแทรกเฉพาะคำสั่ง

ทำไมมันเป็นคำถามจริง เนื่องจากการอัปโหลด mysqldumps ช้าน่าเกลียดถ้า DB มากกว่า 2Gb และคุณไม่สามารถโคลนตาราง InnoDB เพียงแค่คัดลอกไฟล์ DB (เช่นการสำรองสแน็ปช็อต)


0

SQL ที่แสดงคำสั่ง SQL จำเป็นต้องรันเพื่อทำซ้ำฐานข้อมูลจากฐานข้อมูลหนึ่งไปยังอีกฐานข้อมูลหนึ่ง สำหรับแต่ละตารางจะมีการสร้างคำสั่งตารางและคำสั่งแทรก ถือว่าฐานข้อมูลทั้งสองอยู่บนเซิร์ฟเวอร์เดียวกัน:

select @fromdb:="crm";
select @todb:="crmen";

SET group_concat_max_len=100000000;


SELECT  GROUP_CONCAT( concat("CREATE TABLE `",@todb,"`.`",table_name,"` LIKE `",@fromdb,"`.`",table_name,"`;\n",
"INSERT INTO `",@todb,"`.`",table_name,"` SELECT * FROM `",@fromdb,"`.`",table_name,"`;") 

SEPARATOR '\n\n')

as sqlstatement
 FROM information_schema.tables where table_schema=@fromdb and TABLE_TYPE='BASE TABLE';

-1

Mysqldump ไม่ใช่วิธีแก้ปัญหาที่ไม่ดี วิธีที่ง่ายที่สุดในการทำซ้ำฐานข้อมูล:

mysqldump -uusername -ppass dbname1 | mysql -uusername -ppass dbname2

นอกจากนี้คุณสามารถเปลี่ยนเอนจิ้นการจัดเก็บด้วยวิธีนี้:

mysqldump -uusername -ppass dbname1 | sed 's/InnoDB/RocksDB/' | mysql -uusername -ppass dbname2

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.