如何将大型(14 GB)MySQL转储文件导入新的MySQL数据库?

时间:2012-12-05 06:03:56

标签: mysql bigdata

如何将大型(14 GB)MySQL转储文件导入新的MySQL数据库?

13 个答案:

答案 0 :(得分:155)

我四处寻找,只有这个解决方案帮助了我:

mysql -u root -p

set global net_buffer_length=1000000; --Set network buffer length to a large byte number

set global max_allowed_packet=1000000000; --Set maximum allowed packet size to a large byte number

SET foreign_key_checks = 0; --Disable foreign key checking to avoid delays,errors and unwanted behaviour

source file.sql --Import your sql dump file

SET foreign_key_checks = 1; --Remember to enable foreign key checks when procedure is complete!

答案是here

答案 1 :(得分:23)

您是否尝试过直接使用mysql命令行客户端?

mysql -u username -p -h hostname databasename < dump.sql

如果你不能这样做,谷歌可以找到任意数量的实用工具,帮助你将大型转储导入MySQL,如BigDump

答案 2 :(得分:4)

首先打开 - &gt;命令行

cd..

cd..

f: -- xampp installed drive

cd xampp/mysql/bin

mysql -u root -p

set global net_buffer_length=1000000; --Set network buffer length to a large byte number

set global max_allowed_packet=1000000000; --Set maximum allowed packet size to a large byte number

SET foreign_key_checks = 0; --Disable foreign key checking to avoid delays,errors and unwanted behaviour

use DATABASE_NAME;

source G:\file.sql; --Import your sql dump file

SET foreign_key_checks = 1; --Remember to enable foreign key checks when procedure is complete!

答案 3 :(得分:2)

我将我的发现发布在我所看到的一些没有提到我遇到的内容中,并且显然这甚至会击败BigDump,所以检查一下:

我试图通过Linux命令行加载一个500兆的转储并继续使用#34; Mysql服务器已经消失了#34;错误。 my.conf中的设置没有帮助。结果证明是......我正在做一个大的扩展插件,如:

    insert into table (fields) values (a record, a record, a record, 500 meg of data);

我需要将文件格式化为单独的插入,如下所示:

    insert into table (fields) values (a record);
    insert into table (fields) values (a record);
    insert into table (fields) values (a record);
    Etc.

为了生成转储,我使用了类似的东西,它就像一个魅力:

    SELECT 
        id,
        status,
        email
    FROM contacts
    INTO OUTFILE '/tmp/contacts.sql'
    FIELDS TERMINATED BY ','
    OPTIONALLY ENCLOSED BY '"'
    LINES STARTING BY "INSERT INTO contacts (id,status,email) values ("
    TERMINATED BY ');\n'

答案 4 :(得分:2)

简单的解决方案是运行此查询: mysql -h yourhostname -u username -p databasename < yoursqlfile.sql

如果要使用进度条导入,请尝试以下操作: pv yoursqlfile.sql | mysql -uxxx -pxxxx databasename

答案 5 :(得分:2)

我制作了一个PHP脚本,该脚本旨在导入由phpmyadmin或mysql dump(从cpanel)生成的大型数据库转储。称为PETMI,您可以在[project page] [gitlab page]处下载。

它通过拆分一个来工作。 sql文件分成更小的文件,称为拆分,并一次处理每个拆分。用户无法在phpmyadmin中手动处理无法处理的拆分。可以像在sql转储中一样容易地进行编程,每个命令都在新行上。 sql dumps中的某些内容在phpmyadmin导入中有效,而在mysqli_query中则无效,因此这些行已从拆分中删除。

已通过1GB数据库测试。必须将其上传到现有网站。 PETMI是开源的,示例代码可以在Gitlab上看到。

一位主持人要求我提供一些示例代码。我在打电话,请原谅。

这是创建拆分的代码。

                 //gets the config page
                  if (isset($_POST['register']) && $_POST['register'])
                {
                 echo " <img src=\"loading.gif\">";
        $folder = "split/";
        include ("config.php");
        
        $fh = fopen("importme.sql", 'a') or die("can't open file");
        $stringData = "-- --------------------------------------------------------";
        fwrite($fh, $stringData);
        fclose($fh);
        
        
        $file2 = fopen("importme.sql","r");
        
        //echo "<br><textarea class=\"mediumtext\" style=\"width: 500px; height: 200px;\">";
        $danumber = "1";
        while(! feof($file2)){
            //echo fgets($file2)."<!-- <br /><hr color=\"red\" size=\"15\"> -->"; 
            $oneline = fgets($file2); //this is fgets($file2) but formatted nicely
            //echo "<br>$oneline";
            
            $findme1  = '-- --------------------------------------------------------';
            $pos1 = strpos($oneline, $findme1);
            $findme2  = '-- Table structure for';
            $pos2 = strpos($oneline, $findme2);
            $findme3  = '-- Dumping data for';
            $pos3 = strpos($oneline, $findme3);
            $findme4  = '-- Indexes for dumped tables';
            $pos4 = strpos($oneline, $findme4);
            $findme5  = '-- AUTO_INCREMENT for dumped tables';
            $pos5 = strpos($oneline, $findme5);
            if ($pos1 === false && $pos2 === false && $pos3 === false && $pos4 === false && $pos5 === false) {

                // setcookie("filenumber",$i);
                // if ($danumber2 == ""){$danumber2 = "0";} else { $danumber2 = $danumber2 +1;}                 
                $ourFileName = "split/sql-split-$danumber.sql";
                // echo "writing danumber is $danumber";
                $ourFileHandle = fopen($ourFileName, 'a') or die("can't edit file. chmod directory to 777");

                $stringData = $oneline;
                $stringData = preg_replace("/\/[*][!\d\sA-Za-z@_='+:,]*[*][\/][;]/", "", $stringData);
                $stringData = preg_replace("/\/[*][!]*[\d A-Za-z`]*[*]\/[;]/", "", $stringData);
                $stringData = preg_replace("/DROP TABLE IF EXISTS `[a-zA-Z]*`;/", "", $stringData);
                $stringData = preg_replace("/LOCK TABLES `[a-zA-Z` ;]*/", "", $stringData);
                $stringData = preg_replace("/UNLOCK TABLES;/", "", $stringData);

                fwrite($ourFileHandle, $stringData);
                fclose($ourFileHandle);
            
            } else {
                    //write new file;
                    if ($danumber == ""){$danumber = "1";} else { $danumber = $danumber +1;}
                    $ourFileName = "split/sql-split-$danumber.sql"; 
                    //echo "$ourFileName has been written with the contents above.\n";
                    
                    $ourFileName = "split/sql-split-$danumber.sql";
                    $ourFileHandle = fopen($ourFileName, 'a') or die("can't edit file. chmod directory to 777");
                    $stringData = "$oneline";
                    fwrite($ourFileHandle, $stringData);
                    fclose($ourFileHandle);
            }
        }
        //echo "</textarea>";
        
    
    fclose($file2);

这是导入拆分的代码

<?php
ob_start();
// allows you to use cookies
include ("config.php");
//gets the config page
if (isset($_POST['register']))
{
echo "<div id**strong text**=\"sel1\"><img src=\"loading.gif\"></div>";

// the above line checks to see if the html form has been submitted
$dbname = $accesshost;
$dbhost = $username;
$dbuser = $password;
$dbpasswd = $database;
$table_prefix = $dbprefix;
//the above lines set variables with the user submitted information
    //none were left blank!  We continue...


//echo "$importme";

echo "<hr>";

$importme = "$_GET[file]";
$importme = file_get_contents($importme);
//echo "<b>$importme</b><br><br>";
$sql = $importme;
$findme1  = '-- Indexes for dumped tables';
$pos1 = strpos($importme, $findme1);
$findme2 = '-- AUTO_INCREMENT for dumped tables';
$pos2 = strpos($importme, $findme2);

$dbhost = '';
@set_time_limit(0);


if($pos1 !== false){
    $splitted = explode("-- Indexes for table", $importme);
    // print_r($splitted);
    for($i=0;$i<count($splitted);$i++){
        $sql = $splitted[$i];
        $sql = preg_replace("/[`][a-z`\s]*[-]{2}/", "", $sql);
        
        // echo "<b>$sql</b><hr>";
        if($table_prefix !== 'phpbb_') $sql = preg_replace('/phpbb_/', $table_prefix, $sql);
        $res = mysql_query($sql);
    }
    if(!$res) { echo '<b>error in query </b>', mysql_error(), '<br /><br>Try importing the split .sql file in phpmyadmin under the SQL tab.'; /* $i = $i +1; */ } else {
    echo ("<meta http-equiv=\"Refresh\" content=\"0; URL=restore.php?page=done&file=$filename\"/>Thank You! You will be redirected");
    }   
 
} elseif($pos2 !== false){
    $splitted = explode("-- AUTO_INCREMENT for table", $importme);
    // print_r($splitted);
    for($i=0;$i<count($splitted);$i++){
        $sql = $splitted[$i];
        $sql = preg_replace("/[`][a-z`\s]*[-]{2}/", "", $sql);
        
        // echo "<b>$sql</b><hr>";
        if($table_prefix !== 'phpbb_') $sql = preg_replace('/phpbb_/', $table_prefix, $sql);
        $res = mysql_query($sql);
    }
    if(!$res) { echo '<b>error in query </b>', mysql_error(), '<br /><br>Try importing the split .sql file in phpmyadmin under the SQL tab.'; /* $i = $i +1; */ } else {
    echo ("<meta http-equiv=\"Refresh\" content=\"0; URL=restore.php?page=done&file=$filename\"/>Thank You! You will be redirected");
    }   
} else {
    if($table_prefix !== 'phpbb_') $sql = preg_replace('/phpbb_/', $table_prefix, $sql);
    $res = mysql_query($sql);
    if(!$res) { echo '<b>error in query </b>', mysql_error(), '<br /><br>Try importing the split .sql file in phpmyadmin under the SQL tab.'; /* $i = $i +1; */ } else {
    echo ("<meta http-equiv=\"Refresh\" content=\"0; URL=restore.php?page=done&file=$filename\"/>Thank You! You will be redirected");
    }


 }




//echo 'done (', count($sql), ' queries).';

}

    

答案 6 :(得分:0)

对于Windows,我使用Navicat Premium。它允许您将数据库对象从一个数据库传输到另一个数据库,或传输到sql文件。目标数据库可以与源在同一服务器上,也可以在另一台服务器上。

Navicat Online Manual for windows

答案 7 :(得分:0)

使用 source 命令导入大型数据库

mysql -u username -p

> source sqldbfile.sql

这可以导入任何大型数据库

答案 8 :(得分:0)

在最近的项目中,我们面临着处理和处理大量数据的挑战。我们的客户为我们提供了50个CSV文件,大小从30 MB到350 MB不等,总共包含大约2000万行数据和15列数据。我们的最终目标是将数据导入并处理到MySQL关系数据库中,以用于支持我们还开发的前端PHP脚本。现在,使用如此大或更大的数据集并不是最简单的任务,并且在处理它时,我们想花一些时间来分享一些在使用像这样的大型数据集时应该考虑和了解的事情。

1。预先分析您的数据集 我对第一步的压力还不够大!在完全导入数据之前,请确保您花时间分析正在使用的数据。从长远来看,了解所有数据代表什么,与什么操作相关的列以及需要进行哪种类型的操作,最终将节省您的时间。

2。 LOAD DATA INFILE是您的朋友 如果您继续尝试通过PHPMyAdmin之类的工具尝试常规CSV插入,则很难导入像我们处理过的(和较大的)文件一样的大数据文件。由于上载大小限制和服务器超时,不仅在很多情况下它会失败,因为您的服务器将无法处理像某些数据文件一样大的文件上载,而且即使成功,该过程可能也要花费数小时取决于我们的硬件。创建SQL函数LOAD DATA INFILE来处理这些大型数据集,并将大大减少处理导入过程所需的时间。值得注意的是,这可以通过PHPMyAdmin执行,但是您仍然可能存在文件上传问题。在这种情况下,您可以将文件手动上传到服务器,然后从PHPMyAdmin执行(有关更多信息,请参见其手册),或通过SSH控制台执行命令(假设您拥有自己的服务器)

LOAD DATA INFILE '/mylargefile.csv' INTO TABLE temp_data FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'

3。 MYISAM与InnoDB 大型或小型数据库,花一点时间考虑要为项目使用哪种数据库引擎总是很不错的。您将要了解的两个主要引擎是MYISAM和InnoDB,每个引擎都有其自身的优缺点。简而言之,要考虑的事情如下:

MYISAM

  • 降低内存使用量
  • 允许全文搜索
  • 表级别锁定-写入时锁定整个表
  • 非常适合阅读密集型应用程序

InnoDB

  • 列表项
  • 使用更多的内存
  • 不支持全文搜索
  • 更快的性能
  • 行级锁定–写时锁定单行
  • 非常适合读/写密集型应用

4。仔细规划设计 MySQL Analyze您的数据库设计/结构将成为其性能的重要因素。在计划不同的字段并分析数据以找出最佳字段类型,默认值和字段长度时,请花点时间。您想要容纳适量的数据,并在数据无法保证时避免使用varchar列和过大的数据类型。完成数据库后的另一个步骤是,要查看MySQL建议将所有不同字段用作字段类型的建议。您可以通过执行以下SQL命令来做到这一点:

ANALYZE TABLE my_big_table

结果将是对每列信息的描述,以及对应该是哪种数据类型以及适当长度的建议。现在,您不一定要遵循建议,因为它们仅基于现有数据,但这可能有助于您走上正确的轨道并激发您的思考

5。索引或不索引 对于如此大的数据集,根据对前端数据的需要在数据上创建适当的索引非常重要,但是如果您打算事先处理数据,则不要在索引上放置太多索引数据。它不仅会使您的SQL表变大,而且还会减慢某些操作,例如列的增加,减少和其他索引编制。对于我们的数据集,我们需要获取刚刚导入的信息,并将其分解为几个不同的表以创建关系结构,并获取某些列并将信息拆分为其他列。我们在几乎可以帮助我们进行操纵的最少量列上放置了索引。总而言之,我们采用了一个包含2000万行数据的大表,并将其信息分为6个不同的表,表中包含主要数据以及根据现有内容创建的新数据。我们通过编写小的PHP脚本来解析和移动数据来完成所有这些工作。

6。寻找平衡 从编程的角度来看,处理大型数据库的很大一部分是速度和效率。将所有数据都放入数据库中非常好,但是如果您编写的用于访问数据的脚本很慢,那又有什么意义呢?使用大型数据集时,花时间了解脚本正在执行的所有查询并创建索引以尽可能帮助这些查询非常重要。一种分析查询内容的方法是执行以下SQL命令:

EXPLAIN SELECT some_field FROM my_big_table WHERE another_field='MyCustomField';

通过在查询开始处添加EXPLAIN,MySQL将吐出信息,描述其尝试使用,使用和使用的索引。我将这一点标记为“寻找平衡”,因为尽管索引可以帮助您的脚本更快地执行,但也可以轻松地使其运行缓慢。您需要确保为需要的索引以及仅需要的索引。每个索引都会占用磁盘空间,并增加表的开销。每次对表进行编辑时,都必须为该特定行重建索引,并且在这些行上拥有的索引越多,花费的时间就越长。一切都归结为创建智能索引,高效的SQL查询以及最重要的基准测试,以便您了解每个查询的功能以及执行该操作所需的时间。

7。索引打开,索引关闭 当我们处理数据库和前端脚本时,客户端和我们都开始注意到一些需要更改以及需要更改数据库的小事情。其中一些更改涉及添加/删除列以及更改列类型。由于我们已经在数据上设置了许多索引,因此进行任何这些更改都需要服务器做一些认真的工作,以保持索引就位并处理所有修改。在我们的小型VPS服务器上,某些更改可能需要6个小时以上的时间才能完成…对于我们能够进行快速开发肯定没有帮助。解决方案?关闭索引!有时最好关闭索引,进行更改,然后再重新打开索引…,尤其是当您需要进行许多不同的更改时。在关闭索引的情况下,更改要花费几秒钟到几分钟而不是几小时。当我们对更改感到满意时,我们只需重新打开索引即可。当然,这花费了相当长的时间来重新索引所有内容,但是至少能够一次重新索引所有内容,从而减少了一次一个地进行这些更改所需的总时间。操作方法如下:

禁用索引:ALTER TABLE my_big_table DISABLE KEY

启用索引:ALTER TABLE my_big_table ENABLE KEY

8。为MySQL进行调优 在使数据库和脚本快速运行方面,请不要忽略服务器。您的硬件需要与数据库和脚本一样多的关注和调整。特别是,查看您的MySQL配置文件以查看可以进行哪些更改以更好地提高其性能非常重要。我们遇到的一个很棒的小工具是MySQL Tuner http://mysqltuner.com/。这是一个快速的Perl小脚本,您可以将其直接下载到服务器并通过SSH运行,以查看可能要对配置进行的更改。请注意,在运行调谐器之前,您应该积极使用前端脚本和数据库几天,以使调谐器具有要分析的数据。在新服务器上运行它只会提供最少的信息和调整选项。我们发现在两周内每隔几天使用调谐器脚本非常有用,以查看它会提出什么建议,最后,我们显着提高了数据库性能。

9。不要害怕 开始使用SQL可能具有挑战性,而处理非常大的数据集只会使难度变得更大。不要害怕去找那些知道大型数据集正在做什么的专业人士。最终,您将获得优质的产品,更快的开发和更快的前端性能。对于大型数据库,有时需要专业的经验丰富的眼睛来寻找所有可能降低数据库性能的小警告。

答案 9 :(得分:0)

我长期以来一直试图为这个问题找到一个好的解决方案。最后我想我有一个解决方案。据我所知,max_allowed_packet 没有上限。所以去设置 my.cnf 说 max_allowed_packet=300M

现在做 mysql> source sql.file 不会做得更好,因为转储文件,insert 语句被分成 1mb 大小。所以我的 45gb 文件插入计数是 ~: 45bg/1mb。

为了解决这个问题,我用 php 解析了 sql 文件,并使插入语句变成我想要的大小。就我而言,我已将数据包大小设置为 100mb。所以我减少了插入字符串。在另一台机器上,我有 300M 的数据包大小并插入 200M,它可以工作。

由于所有表的总大小约为 1.2tb,因此我按数据库逐表导出。所以我每个表有一个 sql 文件。如果您的代码不同,则必须相应地调整代码。

<?php
global $destFile, $tableName;
function writeOutFile(&$arr)
{
    echo " [count: " . count($arr) .']';
    if(empty($arr))return;
    global $destFile, $tableName;
    $data='';
    //~ print_r($arr);
    foreach($arr as $i=>$v)
    {
        $v = str_replace(";\n", '', $v);
        //~ $v = str_replace("),(", "),\n(", $v);
        $line = ($i==0? $v: str_replace("INSERT INTO `$tableName` VALUES",',', $v));
        $data .= $line;
    }
    $data .= ";\n";
    file_put_contents($destFile, $data, FILE_APPEND);
}
$file = '/path/to/sql.file';
$tableName = 'tablename';
$destFile = 'localfile.name';
file_put_contents($destFile, null);
$loop=0;
$arr=[];

$fp = fopen($file, 'r');
while(!feof($fp))
{
    $line = fgets($fp);
    if(strpos($line, "INSERT INTO `")!==false)$arr[]=$line;
        else
        {writeOutFile($arr); file_put_contents($destFile, $line, FILE_APPEND);$arr=[];continue;}
    
    $loop++;
    if(count($arr)==95){writeOutFile($arr);$arr=[];}
    echo "\nLine: $loop, ". count($arr);
}

?>

这对您的工作方式将取决于您的硬件。但所有事情都保持不变,这个过程会成倍地加速我的进口。我没有任何基准可以分享,这是我的工作经验。

答案 10 :(得分:-4)

导航到C:\ wamp64 \ alias \ phpmyadmin.conf并从:

更改
php_admin_value upload_max_filesize 128M
php_admin_value post_max_size 128M

php_admin_value upload_max_filesize 2048M
php_admin_value post_max_size 2048M

或更多 :)

答案 11 :(得分:-4)

根据mysql文档,这些都不起作用!人们关注! 所以我们将test.sql上传到test_db 在shell中输入:

mysql --user = user_name --password = yourpassword test_db&lt; d:/test.sql

这肯定有效!

感谢。

答案 12 :(得分:-8)

你需要

  • 来自下载的Bigdump脚本bigdump.php
  • 由phpMyAdmin或其他工具创建的数据库转储文件,我们称之为dump.sql。您也可以使用GZip压缩转储文件,我们称之为dump.gz。
  • 访问mySQL数据库的帐户
  • 安装了PHP的某些Web服务器的访问帐户。此Web服务器必须能够连接到mySQL数据库。如果您的Web服务器和mySQL服务器来自同一ISP,则可能存在此功能。
  • 一些优秀的文本编辑器,如Notepad ++,用于编辑配置文件。
  • 某些FTP客户端将文件上传到Web服务器。
  • 关于文件,PHP,mySQL数据库,phpMyAdmin,FTP和HTTP
  • 的常识