【发布时间】:2019-05-22 21:23:59
【问题描述】:
我正在尝试使用 pg-promise 和 pg-query-stream 对查询流的每一行执行插入查询。使用我的方法,每次执行查询都会增加内存使用量。
我还将问题缩小到只在流期间执行任何查询,而不仅仅是插入。我目前在流上侦听“数据”事件、暂停流、执行查询并恢复流。我还尝试将查询流通过管道传输到执行查询的可写流中,但我收到数据库连接已关闭的错误。
let count = 0;
const startTime = new Date();
const qs = new QueryStream('SELECT 1 FROM GENERATE_SERIES(1, 1000000)');
db.stream(qs, stream => {
stream.on('data', async () => {
count++;
stream.pause();
await db.one('SELECT 1');
if (count % 10000 === 0) {
const duration = Math.round((new Date() - startTime) / 1000);
const mb = Math.round(process.memoryUsage().heapUsed/1024/1024);
console.log(`row ${count}, ${mb}MB, ${duration} seconds`);
}
stream.resume();
});
});
我预计内存使用量会在一个常数值附近徘徊,但输出如下所示:
row 10000, 105MB, 4 seconds
row 20000, 191MB, 6 seconds
row 30000, 278MB, 9 seconds
row 40000, 370MB, 10 seconds
row 50000, 458MB, 14 seconds
到达第 60000 行需要 10 多分钟。
更新:
我编辑了上面的代码以包含 async/await 以等待内部查询完成,并将系列增加到 10,000,000。我使用 512MB 内存运行节点进程,当接近该限制时程序明显变慢但不会崩溃。这个问题出现在 v10 而不是 v11+ 的节点上。
【问题讨论】:
-
您确定是额外的行
db.one('SELECT 1');导致了额外的内存使用,而不是其他原因吗?另外,.then.catch在哪里?没有,这是一个松散的承诺。 -
又看了一遍,马上就发现了问题。我不是在等待内部查询完成。添加 async/await 修复了它。我的完整应用程序中仍然存在内存泄漏以及许多其他逻辑,所以我会看看是否可以将其简化为简单的内容并在此处发布。
标签: node.js pg-promise