我试图将大文件导入数据库。在尝试通过mySQL导入csv文件失败后,我决定创建一个可以读取文件并逐个插入记录的小节点脚本。
我有大约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
我不熟悉节点,所以我真的不知道这意味着什么。我认为它与从一个比查询移动得更快的循环内部调用的查询有关,但是我不确定它并且如果是这样的话就不知道如何处理它。 / p>
感谢任何帮助。
对不起,如果我的英语失败了。
答案 0 :(得分:-1)
问题是你在第一个查询结束后结束了与数据库的连接,所以,只有那些有足够时间去数据库的查询量应该被执行,我的猜测是只有第一个查询将会插入(也许我错了)。
由于您可能正在执行“一次性脚本”节点,因此您可以解决问题,只需删除该行,如下所示:
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
}
});
});
如果您的脚本多次有用(每月一次,每天一次或类似的话),我会采用更好的解决方案,可能使用 async 和连接池。