2015-11-04 126 views
1

我想將大文件導入數據庫。在許多失敗嘗試通過mySQL導入爲csv文件後,我決定創建一個小節點腳本,它可以讀取文件並逐個插入記錄。使用node.js插入很多行到mysql

我有大約10個不同格式的每個80mb的文件。當前的腳本是一個文件,該文件對每一行,並沒有更多的ID(這個特殊的表格只包含一個id字段和狀態字段),這是其當前狀態:

var mysql  = require('mysql'); 
var connection = mysql.createConnection({ 
    host  : 'hostname', 
    user  : 'username', 
    password : 'password', 
    database : 'database' 
}); 

var rl = require('readline').createInterface({ 
    input: require('fs').createReadStream('fileToRead.txt') 
}); 

connection.connect(); 
rl.on('line', function (line) { 
    var query = 'REPLACE INTO database.tablename(field1,field2) VALUES ("'+line+'",0);'; 
    connection.query(query, function(err) { 
     if (err) { 
      console.log("ERR:"+err); 
      connection.end(); 
     } 
    }); 
}); 

它工作正常大約十到十二行,然後拋出以下錯誤:

<--- Last few GCs ---> 

    51338 ms: Scavenge 699.0 (738.6) -> 699.0 (738.6) MB, 8.7/0 ms (+ 15.0 ms i 
n 1 steps since last GC) [allocation failure] [incremental marking delaying mark 
-sweep]. 
    53709 ms: Mark-sweep 699.0 (738.6) -> 698.9 (738.6) MB, 2360.5/0 ms (+ 15.0 
ms in 2 steps since start of marking, biggest step 15.0 ms) [last resort gc]. 
    56065 ms: Mark-sweep 698.9 (738.6) -> 698.9 (738.6) MB, 2360.2/0 ms [last r 
esort gc]. 



    <--- JS stacktrace ---> 
==== JS stack trace ========================================= 

Security context: 1DF25599 <JS Object> 
    1: emit [events.js:~117] [pc=23C30364] (this=1027D245 <a Protocol with map 3 
2339A39>,type=1DF4D5B1 <String[7]: enqueue>) 
    2: arguments adaptor frame: 2->1 
    3: _enqueue [path\node_modules\mysql\lib\protocol\ 
Protocol.js:~128] [pc=107BD3D8] (this=1027D245 <a Protocol with map 32339A39>,se 
quence=157A3225 <a Query with map 3233C379>) 
    4: /* anonymous */ [path... 

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory 

我不習慣節點,所以我不知道這是什麼意思。我相信它與從查詢中調用的查詢有關,該查詢的運行速度比查詢快,但我不確定,如果情況如此,我不知道如何處理它。

任何幫助表示讚賞。

對不起,如果我的英語失敗。

+0

也許你可以用連續的方式重寫它,我不確定,但它可能會嘗試處理大量的行,並且第一個完成的是關閉連接,阻止其他人運行查詢。 – ergonaut

+0

連接是否在錯誤的情況下關閉?或者是以這樣一種方式構建的'mysql.query'函數,在事務完成後關閉de連接? – porjolovsky

回答

0

問題是,在第一次查詢結束後,您正在結束與數據庫的連接,因此,只有有足夠時間才能訪問數據庫的查詢數量應該執行,我的猜測是隻有第一次將被插入(也許我錯了)。

既然你也許正在做一個「僅一次腳本」節點,你能解決你的問題只是刪除這一行,像這樣:

var mysql  = require('mysql'); 
var connection = mysql.createConnection({ 
    host  : 'hostname', 
    user  : 'username', 
    password : 'password', 
    database : 'database' 
}); 

var rl = require('readline').createInterface({ 
    input: require('fs').createReadStream('fileToRead.txt') 
}); 

connection.connect(); 
rl.on('line', function (line) { 
    var query = 'REPLACE INTO database.tablename(field1,field2) VALUES ("'+line+'",0);'; 
    connection.query(query, function(err) { 
     if (err) { 
      console.log("ERR:"+err); 
      //I am not closing the connection anymore 
     } 
    }); 
}); 

如果你的腳本將是許多有用次(每月一次,每天一次或類似的事情),我會獲得更好的解決方案,可能使用異步和一個連接池。