How do I avoid max connections error in mysql? - mysql

This happens pretty frequently (once a week for about 30-40 minutes), where all of a sudden my database mentions max connections when I try to connect via heidisql, and any apis calls respond with the following error:
Cannot read property 'release' of undefined
I am calling .release() after every query in mysql. Is there something I am missing, am I suppose to call .end as well? I am using nodejs with mysql.
Here is the way I wrap every query and the pool code:
var mysql = require('mysql');
var mysql_pool = mysql.createPool({
connectionLimit: config.mysql.limit,
host: config.mysql.host,
user: config.mysql.user,
password: config.mysql.pw,
database: config.mysql.db //,
// debug: true
});
var qSelect = "SELECT id FROM Users";
var qValues = [];
var qCall = mysql.format(qSelect, qValues);
mysql_pool.getConnection(function(err_pool, connection) {
if (err_pool) {
connection.release();
console.log(' Error getting mysql_pool connection: ' + err_pool);
throw err_pool;
}
connection.query(qCall, function(err, userFound, fields) {
connection.release();
if (err) {
console.log("get user : " + err);
} else {
//some code here
}
});
Can someone please advise, appreciate it.

You should remove first connection.release() used in if loop
if (err_pool) {
console.log(' Error getting mysql_pool connection: ' + err_pool);
throw err_pool;
}

Related

Getting mysql:"Too many connections" despite using createPool in NodeJs

I am using Observables to display real-time data in Angular2+ application and the back-end is written in NodeJs that uses MySQL database. Since I am using Observables, I need tens of millions of connections of MySQL to keep the real-time work going.
But it is not possible to acquire so many connections. So I used pooling where a connection is created from the pool of connections. However, I fail to implement it. I still get the error:
Error: ER_CON_COUNT_ERROR: Too many connections"
How can I close my connections so that the connections are not outnumbered?
Front end code:
angular.component.ts
Observable.interval(10000).subscribe(x => {
this.viewData(Val);
// more functions
console.log(" Observable")
});
NodeJS code:
dashboard.service.js
function viewData(data) {
var sqlQuery = `
select * from TRANSACTION_PAYLOAD where INTERFACE_NAME = 'Highmark' AND (STATUS ='SUCCESS_RESPONSE')`
var deferred = Q.defer();
console.log("INSIDE NODE JS SERVICE");
var host = config.host;
var user = config.user;
var password = config.password;
var database = config.database;
var con = mysql.createPool({
host: host,
user: user,
password: password,
database: database
});
con.getConnection(function (err) {
console.log("Inside .getConnection ")
if (err) deferred.reject(err.name + ': ' + err.message);
con.query(sqlQuery,
function (err, result, fields) {
if (err) deferred.reject(err.name + ': ' + err.message);
console.log(result);
deferred.resolve(result);
});
});
return deferred.promise;
con.close();
}
you are creating mysql pool for every request. You supposed to have single connection pool.
connection pool manages connections made to mysql server automatically.
you need to take out connection pool initialization out of your function.
take the connection pull out
const mysqlConOptions = {
host: host,
user: user,
password: password,
database: database
};
var conPool = mysql.createPool(mysqlConOptions);
inside your function,
conn = await conPool.getConnection();

NodeJs - How to share MySQL pool accross my models to avoid 'ER_CON_COUNT_ERROR'

I'm currently testing my node app using ApacheBench. I run into an issue with my database which is ER_CON_COUNT_ERROR: Too many connections.
I'm using a short library on the top of MySQL node module that you can see just below
var mysql = require('mysql');
var config = require('path/to/config');
var message = require('./myMessageLib.js');
var pool = mysql.createPool({
connectionLimit : 100,
host: config.db.mysql.host,
user: config.db.mysql.user,
password: config.db.mysql.password,
database: config.db.mysql.database
});
var query = function(query_str, values, next) {
pool.getConnection((err, connection) => {
if (err) {
console.error("MySQL Fail to get a connection in pool : " + err);
if (typeof connection !== "undefined")
connection.release();
next(error, null);
return ;
}
connection.query(query_str, values, function(error, data, fields) {
connection.release();
if (error)
if (config.app.env.dev)
throw (error);
else {
next(error, null);
return (message.error("MySQL query failed : " + query_str + " / err : " + error));
}
if (data.length == 0)
next(null);
else
next(data);
})
})
}
exports.query = query;
I use this library in my model by doing something like this
var mysql = require('path/to/mysqllib');
/**
* Class PlayerModel
*/
function PlayerModel() { };
PlayerModel.prototype.get = function(id, next) {
mysql.query("SELECT ....", [id], function(player) {
// stuff
})
}
module.exports = PlayerModel;
The things is on my homepage I use different models like the one presented above and each one launch a query to get some database information. When I launch an ApacheBench with only 50 concurrency levels I got the ER_CON_COUNT_ERROR: Too many connections. So I've got the feeling that the pool isn't well made because it seems that it didn't respect the connections limit of 100 written in the short MySQL lib.
I was thinking about creating and storing the pool in the global nodejs variable to be able to share it correctly accros my modules but I'm not sure it's a good way and maybe also I'm doing something wrong on my pool implentation.
Do you have any idea or improvements to suggest ?
Thanks mates!
I figured out the issue.
My app was deploying in cluster mode. Two process were running at the same time. Because of that, two pools of 100 connections could have been created which is resulting on a total of 200 connections which is higher than the MySQL default connection limit.
Great that found a solution and here's another one with less code.
create a js file, dbconnection.js for example
var mysql = require("mysql");
var pool = mysql.createPool({
connectionLimit: 10,
host: '...',
user: '...',
password: '...',
database: '...',
dateStrings: true
});
exports.connection = {
query: function () {
var queryArgs = Array.prototype.slice.call(arguments),
events = [],
eventNameIndex = {};
pool.getConnection(function (err, conn) {
if (err) {
if (eventNameIndex.error) {
eventNameIndex.error();
}
}
if (conn) {
var q = conn.query.apply(conn, queryArgs);
q.on('end', function () {
conn.release();
});
events.forEach(function (args) {
q.on.apply(q, args);
});
}
});
return {
on: function (eventName, callback) {
events.push(Array.prototype.slice.call(arguments));
eventNameIndex[eventName] = callback;
return this;
}
};
}
};
In the other file where you want to use the connection
var db = require('./dbconnection.js');
And instead of
connection.query
Use
db.connection.query

Received invalid field length error in nodejs with mysql application

I'm getting below error while fetching records (apx 50 rows) from my sql database. My application is developed in nodejs with express.
var common = require(__base + 'routes/common.js');
var dbhelper = require(__base + 'routes/dbhelper.js');
exports.GetStates = function (callback) {
dbhelper.pool.getConnection(function (err, connection) {
// Use the connection
connection.query('CALL GetStates()',
function (err, res) {
connection.release();
if (err) {
common.ActionOutput.Status = common.ActionStatus.Error;
common.ActionOutput.Message = 'System Error: ' + err.message;
} else {
common.ActionOutput.Status = common.ActionStatus.Success;
common.ActionOutput.Result = res[0][0];
}
return callback(JSON.stringify(common.ActionOutput));
});
});
};
dbhelper.js is
// Database connection
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit: 10,
host: 'my ip',
user: 'user',
password: 'pass',,
database: 'ssdsdas'
});
exports.pool = pool;
I ran into the same error message but the causes of our issues might be different. Ultimately, the cause of my issue is that the column names in my stored procedure did not have back ticks (`) resulting in them being treated as variables.
Adding back ticks in my stored procedure body for column names fixed it.

Simple server handling routes and giving error nodejs mysql

I'm trying to write a simple server using nodejs and have the server ship back different queries and/or custom headers/responses based on the routes. However, in the getUsers() function the error keeps getting hit and printing the 'Error querying' to the console instead of printing the email rows. I know the server is connected fine, because I can return a query when I just use the db and return a query with createConnection only using the second example. Any help spotting the error is greatly appreciated. Thanks.
What I'm trying to get done:
var http = require('http');
var mysql = require('mysql');
var url = require('url');
var util = require('util');
var db = mysql.createConnection({
host : "*********",
user : "*********",
password : "*********",
port : '****',
database : '*********'
});
db.connect(function(err) {
console.log('connected');
if (err)
console.error('Error connecting to db' + err.stack);
});
function getUsers() {
db.query('SELECT * FROM users', function(err, rows, fields) {
if (err)
// changed console.error('Error querying');
console.error(err);
if (rows)
console.log('Rows not null');
for (var i in rows) {
console.log(rows[i].email)
}
});
}
var server = http.createServer(function(req, res) {
console.log(req.url);
if (req.url == '/signup') {
console.log("User signing up");
} else if (req.url == '/signin') {
console.log("User signing in");
} else if (req.url == '/new') {
console.log("User request new game");
getUsers();
}
//res.writeHead(200);
//res.end('Hello Http');
});
server.listen(3000);
// changed and commented out db.end();
What does work with querying the db:
var connection = mysql.createConnection({
host : "********",
user : "********",
password : "********",
port : '****',
database : '********'
});
connection.connect();
var queryString = 'SELECT * FROM users';
connection.query(queryString, function(err, rows, fields) {
if (err) throw err;
for (var i in rows) {
console.log('Users: ', rows[i].email);
}
});
connection.end();
The code has been updated with the changes, and the problem was I was closing the database. After changing the error logs as was suggested in the comments, this was the error received.
{ [Error: Cannot enqueue Query after invoking quit.] code: 'PROTOCOL_ENQUEUE_AFTER_QUIT', fatal: false }
I then commented out the
db.end()
and the queries were returned fine.
Thanks for the help.

Node.js http with mysql pooling quits unexpectedly on error

So I started to try node.js this morning and was able to come-up with a http service that handles path requests and can connect to mysql with pooling for multiple transactions.
I am just having problems if ever I tried to make the password wrong, etc the node process quits unexpectedly.
var http = require("http");
var url = require("url");
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'root',
database : 'test'
});
...
var pathname = url.parse(request.url).pathname;
var url_parts = url.parse(request.url, true);
var query = url_parts.query;
...
var table = query.table;
var sql = "SELECT * FROM " + table + "";
...
pool.getConnection(function(err, connection) {
console.log(err);
connection.on('error', function(err) {
console.log(err.code);
});
// Use the connection
connection.query(sql, function(err, rows) {
if (err) throw err;
console.log(rows);
response.writeHead(200, {
"Content-Type" : "application/json"
});
response.write(JSON.stringify(rows, null, 0));
connection.end();
response.end();
});
console.log(connection.sql);
console.log(connection.query);
});
Appreciate any help on how can I make it not to QUIT! and just say the damn error.
Anyway, I used forever to make this node.js to never quit on me, in-cases of error.
You use throw err, but don t catch it anywhere, causing node a UncaughtException Error, closing the app.