使用Lambda连接Aurora Reader Endpoint时遇Pool is closed问题求助
Hey, I see exactly what's causing your issue here! Let's break this down and fix it step by step.
The Root Cause
Your Lambda function leverages execution container reuse (a standard Lambda optimization to speed up follow-up invocations), but your code is calling connection.end() after a successful query. This shuts down the entire MySQL connection pool after the first successful request. When the next invocation reuses the same container, the pool is already closed—hence the "Pool is closed" error you're seeing.
Looking at your original code:
var AWS = require("aws-sdk"); var mysql = require('mysql'); const client = new AWS.DynamoDB.DocumentClient({region : 'eu-west-1'}); var connection = mysql.createPool({ host : "*******************", user : "*****", password : "******", database : "mydb", port : "3306" }); exports.handler = (event, context, callback) => { //var id = parseInt(event.id); connection.query("select * from demo where id=3;", function (error, results, fields) { if (error) { if (error) throw error; } else { connection.end(); // This line is breaking subsequent invocations! } }); };
That connection.end() call terminates the entire pool, which defeats the purpose of using a pool in a serverless environment where container reuse is common.
The Fixes
Here are two key adjustments to resolve this:
1. Remove connection.end() entirely
Connection pools are built to be reused across multiple requests. Let the pool manage individual connections automatically—you don't need to shut down the entire pool after every query.
2. Properly handle Lambda's event loop (optional but recommended)
By default, Lambda waits for the event loop to empty before marking a request as complete. To ensure your function finishes as soon as the query is done (without waiting for idle pool connections), set context.callbackWaitsForEmptyEventLoop = false; at the start of your handler.
Updated Working Code
var AWS = require("aws-sdk"); var mysql = require('mysql'); const client = new AWS.DynamoDB.DocumentClient({region : 'eu-west-1'}); // Create the pool once (outside the handler) so it's reused across Lambda invocations var connection = mysql.createPool({ host : "*******************", user : "*****", password : "******", database : "mydb", port : "3306" }); exports.handler = (event, context, callback) => { // Tell Lambda not to wait for the event loop to empty context.callbackWaitsForEmptyEventLoop = false; //var id = parseInt(event.id); connection.query("select * from demo where id=3;", function (error, results, fields) { if (error) { console.error("Query failed:", error); callback(error); // Properly pass errors to Lambda's callback } else { callback(null, results); // Return successful results via callback } }); };
Additional Tips
- Initializing the connection pool outside the handler function is critical—it ensures the pool is created once and reused across invocations, boosting performance and preventing too many concurrent connections to your Aurora instance.
- Avoid throwing errors directly in the handler; use Lambda's
callback(or async/await syntax for newer code) to properly signal success or failure, which helps Lambda manage invocations cleanly.
内容的提问来源于stack exchange,提问作者ABCD

