AWS Aurora MySQL+NodeJS导入数据内存不足,求非升级实例解决方案
无需扩容解决Aurora MySQL导入数据内存不足问题
问题详情
向配备4GB内存的AWS Aurora MySQL(db.t4g.medium)实例导入10万条数据(20MB文件)时,触发内存不足错误,错误信息如下:
Error: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space at PromiseConnection.query (/var/task/node_modules/mysql2/promise.js:93:22) at Function.getQueryResult (/var/task/wpcn-connect-to-rds/rdsProxyDBManager.js:10:49) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async Runtime.exports.handler (/var/task/wpcn-connect-to-rds/index.js:48:21) { code: 'ER_OUT_OF_RESOURCES', errno: 1041 }
Invoke Error:
{"errorType":"Error","errorMessage":"Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space","code":"ER_OUT_OF_RESOURCES","message":"Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space","errno":1041}
当前使用的Node.js连接代码:
static async getQueryResult (secret, query){ const connection = await mysql2.createConnection(secret); const [rows, fields] = await connection.query(query); connection.end(); return { 'statusCode': 200, 'body': rows } }
数据库连接配置(secret):
secret = { host, user: username, password: password, port: port, waitForConnections: true, multipleStatements: true, connectionLimit: 10, queueLimit: 0 }
导入文件包含10万条如下格式的单条INSERT语句:
INSERT INTO table1 (id,subject,description,progress,hours,startdt,duedt,private) VALUES(null,'test','1','0','0','2022-08-02 00:00:00.000','2022-08-02 00:00:00.000','1'); INSERT INTO table1 (id,subject,description,progress,hours,startdt,duedt,private) VALUES(null,'XSS','','1','1','2022-08-02 00:00:00.000','2022-08-02 00:00:00.000','0');
无需扩容的解决方案
以下方案无需增加RAM或升级实例类型即可解决问题:
- 合并为批量INSERT语句:将多条单条INSERT合并成一条批量插入语句,格式为
INSERT INTO table1 (...) VALUES (...), (...), (...)。MySQL处理批量插入的内存效率远高于单条语句批量执行,同时减少SQL解析的内存开销。建议每批次合并1000-2000条记录,平衡效率与内存占用。 - 分批次执行导入:不要一次性将10万条语句全部传入
connection.query,而是将文件内容拆分成多个小批次(比如每1000条为一批),逐批次执行导入,每完成一批再处理下一批,避免大量未执行的SQL语句占用内存。 - 关闭
multipleStatements配置:当前配置中开启了multipleStatements: true,该选项允许单query执行多条语句,但会额外消耗内存。改用批量INSERT后无需此配置,关闭它可降低内存占用。 - 流式读取导入文件:如果当前是一次性读取整个20MB文件到内存中作为query参数,改为流式读取文件(比如使用Node.js的
fs.createReadStream),每次读取并处理一部分内容,避免大文件占用内存。 - 优化Aurora MySQL内存参数:通过AWS控制台调整实例的参数组,合理分配内存:
- 将
innodb_buffer_pool_size设置为实例内存的40%-50%(比如1.5GB-2GB),这是InnoDB最核心的内存缓存区域; - 降低
sort_buffer_size、join_buffer_size等非核心参数的默认值,减少不必要的内存消耗; - 注意参数调整不要超过实例总内存限制,避免触发OOM。
- 将
- 改用连接池复用连接:当前代码每次创建新连接后立即关闭,改为使用
mysql2.createPool创建连接池,复用已有的连接,减少连接创建与销毁的内存开销,同时保持connectionLimit:10的限制,避免过多连接占用内存。
内容的提问来源于stack exchange,提问作者Rahith R R
相关产品推荐
相关产品推荐

