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


70

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


1
尝试这样做会发生什么?您尝试了什么,得到了什么结果?
Brian Campbell

1
我在本地phpmyadmin中尝试过,我的机器挂了或者超时了。我通过更改执行时间进行了尝试,但这也没有帮助。您可以在php或C或任何第三方软件中给我这个想法,将整个转储分解为小块。
TRN

通常ERROR 2006 (HY000) at line 45: MySQL server has gone away出现在大文件上,而
@Kresimir

Answers:


211

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

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!

答案在这里找到。


7
通过mariadb,将检查最大值: set global net_buffer_length=1048576; set global max_allowed_packet=1073741824;
Nicolas Thery

1
嗯应该可以工作,在每次源命令超时之前,mysql都不会让我“使用数据库” ...
Chris Richardson

@ChrisRichardson就我而言,它让我在源命令之前执行“使用数据库”。我的SQL大小为43 GB。它像魅力一样运作。
MAK Simanto

@MAKSimanto我最终使用脚本将转储分为单独的表并从那里恢复。只是Google mysqldumpsplitter.sh
克里斯·理查森

1
就我而言,它可以工作,但是我应该选择数据库登录到mysql。mysql -u root -p your_database_name然后其余的都是一样的。非常感谢。
inMILD

29

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

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

如果您无法做到这一点,可以通过Googling找到许多实用程序,这些实用程序可以帮助您将大型转储导入到MySQL中,例如BigDump


终端中的mysql命令可用于导入数据库..但不会对其进行优化...
Victor Hugo Arango

就我而言,我不能以mysql这种方式使用客户端。我收到“ MySQL服务器已消失”错误。Kresimir Plese提出解决方案为我工作。
古斯塔沃·斯特劳布

2

我将自己的发现发布在一些我没有看到的遇到的答复中,并且显然这甚至会击败BigDump,因此请检查一下:

我试图通过Linux命令行加载500兆转储,并不断出现“ MySQL服务器已消失”错误。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'

如果您进行了CSV转储,那么它的加载速度会非常快。
polkovnikov.ph 2015年

2

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

  1. 导入前分析您的数据集

    我不能再强调第一步了!在导入之前,请确保您花时间分析正在使用的数据。最终,了解所有数据代表什么,与哪些内容相关的列以及需要进行哪种类型的处理,最终将为您节省时间。

  2. LOAD DATA INFILE是您的朋友

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

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

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

    MYISAM

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

    创新数据库

    • 项目清单
    • 使用更多的内存
    • 不支持全文搜索
    • 更快的性能
    • 行级锁定–写入时锁定单行
    • 非常适合读/写密集型应用
  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可能会非常困难,而处理非常大的数据集只会使难度变得更大。不要害怕去找大数据集的专业人士。最终,您将获得优质的产品,更快的开发和更快的前端性能。对于大型数据库,有时需要专业的经验丰富的眼睛来寻找所有可能降低数据库性能的小警告。


2

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

它通过拆分来工作。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).';

}

    

1

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

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


我可以在Windows上使用pv吗?
Ahmed Suror


-5

根据mysql文档,这些都不行!人们注意!因此,我们将test.sql上传到test_db中,将其输入到外壳中:

mysql --user =用户名--password =您的密码test_db <d:/test.sql


1
这是导入MySQL转储的正常方法。问题是直接要求更大的14gb文件有更好的方法。
Shady Keshk

-6

导航到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

或者更多 :)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.