Solution:
Root Cause: Unreleased Client Connections in Node.js Async Handlers
Node.js database libraries (
mysql2,
sequelize,
knex) rely on connection pools. If queries acquire a connection using
pool.getConnection() but fail to call
connection.release() in error callback branches or async/await catch blocks, the connection remains checked out indefinitely.
Diagnostic Verification:
1.Query connection hosts in MySQL:
sql
SELECT host, db, command, count(*) FROM information_schema.processlist GROUP BY host, db, command;
Step-by-Step Fix:
1.Implement Try/Finally Release Pattern:
Wrap pool connection acquisition in try/finally blocks: javascript
const connection = await pool.getConnection();
try {
const [rows] = await connection.query('SELECT * FROM users');
return rows;
} finally {
connection.release();
}
2.Configure Pool Acquisition Timeouts:
Add timeout limits to prevent indefinite hanging: javascript
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
database: 'test',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
3.Restart Node Application:
Restart the PM2 or systemd process manager.Prevention & Long-Term Monitoring:
Use high-level ORMs like Prisma or Sequelize that manage connection pooling and automatic cleanup lifecycle hooks natively.