Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不使用mysqldump复制/复制数据库_Mysql - Fatal编程技术网

不使用mysqldump复制/复制数据库

不使用mysqldump复制/复制数据库,mysql,Mysql,如果没有对服务器的本地访问,是否有任何方法可以在不使用mysqldump的情况下将MySQL数据库(有内容和无内容)复制/克隆到另一个数据库中 我目前正在使用MySQL 4.0。您可以通过运行以下命令来复制没有数据的表: CREATE TABLE x LIKE y; (见文件) 您可以编写一个脚本,从一个数据库获取SHOW TABLES的输出,并将模式复制到另一个数据库。您应该能够引用架构+表名,如: CREATE TABLE x LIKE other_db.y; 就数据而言,您也可以在My

如果没有对服务器的本地访问,是否有任何方法可以在不使用
mysqldump
的情况下将MySQL数据库(有内容和无内容)复制/克隆到另一个数据库中


我目前正在使用MySQL 4.0。

您可以通过运行以下命令来复制没有数据的表:

CREATE TABLE x LIKE y;
(见文件)

您可以编写一个脚本,从一个数据库获取
SHOW TABLES
的输出,并将模式复制到另一个数据库。您应该能够引用架构+表名,如:

CREATE TABLE x LIKE other_db.y;
就数据而言,您也可以在MySQL中完成,但速度不一定快。创建引用后,可以运行以下操作来复制数据:

INSERT INTO x SELECT * FROM other_db.y;
如果使用MyISAM,最好复制表文件;会快得多。如果将INNODB与一起使用,您也应该能够这样做

如果您最终在SELECT中插入了
,请确保使用
ALTER TABLE x暂时禁用键


EDIT还有一些脚本可能有助于同步数据。它可能不会更快,但您可以在实时数据上运行它们的同步脚本,而无需太多锁定

如果您使用的是Linux,则可以使用以下bash脚本: (它可能需要一些额外的代码清理,但它可以工作……而且比mysqldump | mysql快得多)


我可以看到您说您不想使用
mysqldump
,但我在寻找类似解决方案时访问了此页面,其他人可能也会找到它。考虑到这一点,下面是一种从windows服务器的命令行复制数据库的简单方法:

  • 使用MySQLAdmin或您首选的方法创建目标数据库。在本例中,
    db2
    是目标数据库,将在其中复制源数据库
    db1
  • 在命令行上执行以下语句:
  • mysqldump-h[server]-u[user]-p[password]db1 | mysql-h[server]-u[user]-p[password]db2

    注意:在PHP中,
    -p
    [密码]

    之间没有空格:

    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
    

    注意,作为附加mysql实用程序的一部分,有一个mysqldbcopy命令。。。。
    我真的不知道你所说的“本地访问”是什么意思。 但对于该解决方案,您需要能够通过ssh访问服务器,以复制存储数据库的文件

    我不能使用mysqldump,因为我的数据库很大(7Go,mysqldump失败) 如果2 mysql数据库的版本差异太大,它可能无法工作,您可以使用mysql-V检查您的mysql版本

    1) 将数据从远程服务器复制到本地计算机(vps是远程服务器的别名,可以替换为root@1.2.3.4)

    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
    

    不使用mysqldump克隆数据库表的最佳方法:

  • 创建一个新的数据库
  • 使用以下查询创建克隆查询:

    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';
    
  • 运行输出

  • 但请注意,上面的脚本只是快速克隆表,而不是视图、触发器和用户函数:您可以通过
    mysqldump--no data--triggers--uroot--ppassword
    快速获取结构,然后使用仅克隆insert语句


    为什么这是一个实际问题?因为如果数据库超过2Gb,mysqldumps的上传速度非常慢。而且,您不能仅通过复制数据库文件(如快照备份)来克隆InnoDB表。

    以前的所有解决方案都有一点道理,但是,它们不会复制所有内容。我创建了一个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]));
            }
        }
    }
    

    显示SQL命令的SQL需要运行才能将数据库从一个数据库复制到另一个数据库。对于每个表,都有CREATETABLE语句和insert语句。它假定两个数据库位于同一台服务器上:

    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';
    

    实际上,我想用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;
    

    Mysqldump是一个不错的解决方案。复制数据库的最简单方法:

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

    此外,您还可以通过以下方式更改存储引擎:


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

    这是重复表的工作吗?因为我看到命令是createtableyoucando。我曾经尝试过复制MyISAM数据库的表文件,但这只是破坏了新数据库。可能是我的错,但这绝对不是像有些人说的那么简单的操作。这是一个很好的技巧,我是一个粉丝,但一个重要的注意事项:如果您对InnoDB表使用上面的脚本,并且有外键,那么这不会带来任何外键约束(即使是在被复制的模式之外的约束),将最后一行更改为:
    echo“set foreign_key_checks=0;$fCreateTable;$fInsertData;set foreign_key_checks=1;”;mysql$DBCONN$DBNAME
    这是否也复制了约束数据和表的其他属性?看起来是这样,因为他使用了“SHOW CREATE TABLE”语句,该语句生成一个包含原始视图所有属性的CREATE TABLE。如果您发现@zirael问题,可能是因为脚本无法复制视图。通过将
    SHOW TABLES
    行更改为
    SHOW FULL TABLES,其中Table_Type='BASE Table'
    并添加
    | cut-f 1
    ,可以忽略副本中的视图。完整的行应该是这样的,但将双倒勾替换为单倒勾:“`echo”中表的
    显示完整表,其中表的类型为'BASE TABLE'”| mysql$DBCONN$DBSNAME | tail-n+2 | cut-f1`;do
    我已经通过@jozjan清理了这个脚本,并应用了一些注释
    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';
    
    // 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;