Node.js and MYSQL handle disconnect - mysql

I have cot the following code from a web search and can connect from a client and return data from the database ok.
This is setup on a Mac at home. If I lose the internet connection (usually doing a router re-start to get a faster connection) it recovers okay. However if the connection is down for a while I still have my node.js stuff working but the MYSQL connection is dead. I have to stop and start node.js to re-establish the connection.
var db_config = {
host : 'www.xxxx.com',
user : 'xxx',
password : 'xxx',
};
var connection;
function handleDisconnect() {
connection = mysql.createConnection(db_config); // Recreate the connection, since
// the old one cannot be reused.
connection.connect(function(err) { // The server is either down
if(err) { // or restarting (takes a while sometimes).
console.log('error when connecting to db:', err);
setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect,
} // to avoid a hot loop, and to allow our node script to
}); // process asynchronous requests in the meantime.
// If you're also serving http, display a 503 error.
connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually
handleDisconnect(); // lost due to either server restart, or a
} else { // connnection idle timeout (the wait_timeout
throw err; // server variable configures this)
}
});
}
handleDisconnect();
What is the best way to ensure the connection recovers?
MrWarby.

Related

DB Error: connection lost: server Closed the connection

I'm facing this error when the there are no requests to mysql it goes to idles state and we face this db error. I'm working with node, mysql deployed onto openshift cluster.
How do I keep the db connection alive such that the server never closes the connection?
PFA
Please, lemme know is there any solutions? I'm stuck for past 2 weeks
Update -
Following is the code I'm using
`var connection;
function handleDisconnect() {
connection = mysql.createConnection({
host: config.db.host,
user: config.db.user,
password: config.db.password,
database: config.db.database,
port: config.db.port,
}); // Recreate the connection, since
// the old one cannot be reused.
connection.connect(function (err) {
// The server is either down
if (err) {
// or restarting (takes a while sometimes).
console.log('error when connecting to db:', err);
setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect,
} // to avoid a hot loop, and to allow our node script to
}); // process asynchronous requests in the meantime.
// If you're also serving http, display a 503 error.
connection.on('error', function (err) {
console.log('db error', err);
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
// Connection to the MySQL server is usually
handleDisconnect(); // lost due to either server restart, or a
} else {
// connnection idle timeout (the wait_timeout
throw err; // server variable configures this)
}
});
}
handleDisconnect();`
Since, you are using Node.js, you could use the connection pool.
pooling-connections
Below is a snippet from the link. Notice, connection.release(); It doesn't destroy the connection, but allows the connection to be used again.
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 10,
host : 'example.org',
user : 'bob',
password : 'secret',
database : 'my_db'
});
pool.getConnection(function(err, connection) {
if (err) throw err; // not connected!
// Use the connection
connection.query('SELECT something FROM sometable', function (error, results, fields) {
// When done with the connection, release it.
connection.release();
// Handle error after the release.
if (error) throw error;
// Don't use the connection here, it has been returned to the pool.
});
});

Node.Js- Error: Connection lost: The server closed the connection

Two weeks ago I deployed my first application as part of my new job (Woo Hoo! :)), but every night since I deployed it- the app crashes.
The server-side was built with Node.js, and I'm using XAMPP and MYSQL to run the DataBase.
So this is the error I continuously get:
I was searching for a solution, and found this code:
var connection;
function handleDisconnect() {
connection = mysql.createConnection(con); // Recreate the connection, since
// the old one cannot be reused.
connection.connect(function(err) { // The server is either down
if(err) { // or restarting (takes a while sometimes).
// console.log('error when connecting to db:', err);
setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect,
} // to avoid a hot loop, and to allow our node script to
}); // process asynchronous requests in the meantime.
// If you're also serving http, display a 503 error.
connection.on('error', function(err) {
// console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually
handleDisconnect(); // lost due to either server restart, or a
} else { // connnection idle timeout (the wait_timeout
throw err; // server variable configures this)
}
});
}
handleDisconnect();
I pasted this code after the createConnection function:
var con = mysql.createConnection({
host: "EXAMPLE FOR STUCK OVER FLOW",
user: "EXAMPLE FOR STUCK OVER FLOW",
password: "EXAMPLE FOR STUCK OVER FLOW",
database: "EXAMPLE FOR STUCK OVER FLOW"
});
I will really appreciate for your advice!
Thanks!!!

How to monitor mysql connection status in node?

So this is from https://www.npmjs.com/package/mysql,
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'example.org',
user : 'bob',
password : 'secret'
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
there're 2 parts confuse me,
is connection.connect() making the real connection ? i see it's checking for error. But what happens if everything is ok, but i turn off mysql server after 5 minutes, how to monitor the status pls ?
Even for pool events, i don't see the disconnect event.
for the above code, is there a async/await version for connection.connect() ?
Thanks !
connection.connect is sync you can use it after connection. To handle connection errors you can use:
function handleDisconnect() {
connection = mysql.createConnection(db_config); // Recreate the connection, since
// the old one cannot be reused.
connection.connect(function(err) { // The server is either down
if(err) { // or restarting (takes a while sometimes).
console.log('error when connecting to db:', err);
setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect,
} // to avoid a hot loop, and to allow our node script to
}); // process asynchronous requests in the meantime.
// If you're also serving http, display a 503 error.
connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually
handleDisconnect(); // lost due to either server restart, or a
} else { // connnection idle timeout (the wait_timeout
throw err; // server variable configures this)
}
});
}
By the way everything is explained in node-mysql read me

Nodejs, mysql 'connection lost the server closed the connection'

I connected mysql to nodejs. After a certain period of time, you will get the error :
'Connection lost the server closed the connection'.
I need your help.
An error has occurred and we added the function handleDisconnect. However, once a disconnect is resolved, the second error occurs again from Connection lost the server closed the connection.
I wonder why it should be only once and not the second one.
ps: The description may not be smooth using a translator.
This is part of the app.js file
// connection to databases
var mysql_dbc = require('./config/db_con')();
var connection = mysql_dbc.init();
mysql_dbc.test_open(connection);
// Added Code
handleDisconnect(connection);
function handleDisconnect(client) {
client.on('error', function (error) {
if (!error.fatal) return;
if (error.code !== 'PROTOCOL_CONNECTION_LOST') throw err;
console.error('> Re-connecting lost MySQL connection: ' + error.stack);
mysql_dbc.test_open(connection);
});
};
You can try to use this code to handle server disconnect:
var mysql = require("mysql");
var configuration = {
host: "localhost",
user: "root",
password: "mysql",
database: "blog"
};
var connection;
function handleDisconnect() {
connection = mysql.createConnection(configuration);
connection.connect(function(err) {
if (err) {
console.log("error when connecting to db:", err);
setTimeout(handleDisconnect, 2000);
}else{
console.log("connection is successfull");
}
});
connection.on("error", function(err) {
console.log("db error", err);
if (err.code === "PROTOCOL_CONNECTION_LOST") {
handleDisconnect();
} else {
throw err;
}
});
}
handleDisconnect();
You may lose the connection to a MySQL server due to network problems,
the server timing you out, the server being restarted, or crashing.
All of these events are considered fatal errors.
Re-connecting a connection is done by establishing a new connection.
Once terminated, an existing connection object cannot be re-connected by design.
With Pool, disconnected connections will be removed from the pool freeing up space for a new connection to be created on the next getConnection call.

node js: check mysql connection before a query

I use node js with mysql and want to avoid that the app crash on connection errors.At the moment i use this :
function mysql_handleDisconnect() {
mysql_connection = mysql.createConnection(mysql_config_obj); // Recreate the connection, since
// the old one cannot be reused.
mysql_connection.connect(function(err) { // The server is either down
if(err) { // or restarting (takes a while sometimes).
console.log('error when connecting to db:', err);
mysql_handleDisconnect(); // We introduce a delay before attempting to reconnect,
} // to avoid a hot loop, and to allow our node script to
}); // process asynchronous requests in the meantime.
// If you're also serving http, display a 503 error.
mysql_connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually
mysql_handleDisconnect(); // lost due to either server restart, or a
} else { // connnection idle timeout (the wait_timeout
throw err; // server variable configures this)
}
});
}
mysql_handleDisconnect(mysql_connection);
so this is blocking because it leads to a hot loop if the connection is closed.my problem is, if i add a setTimeout to reestablish connection just every 2 seconds i could get an fatal error when i do a query with "mysql_connection.query('SELECT ...')".in this case the app crashes.
So my question is,if there's a possibility to check the connection before i do a query?
Try using below code in every microservice before doing anything:
if(connection.state === 'disconnected'){
return respond(null, { status: 'fail', message: 'server down'});
}
State of connection to DB could fall in 2 states:
disconnected (when due to DB server down or wrong config use for DB connection is wrong)
authenticated (when DB connection is successfully created to DB server).
So either check state == 'disconnected' or state == 'authenticated'
I know this is an old question but I have found connection.ping( (err) => {...}) to be very useful for health-checks made from load balancers and whatnot.
Every time, while I'm pushing my code in production, the mysql connection is lost. It is a very common problem in production, or local.
My solution is that At every query established the db connection and remove connection after completing the db query.
My solution is to establish the db connection before every query, and then remove the connection after completing the db query.
Step1: Here is the code for dbConnection.js
//this code is for conenct to db
const mysql = require('mysql2');
require('dotenv').config();
module.exports.stablishedConnection = ()=>{
return new Promise((resolve,reject)=>{
const con = mysql.createConnection( {
host: process.env.DB_HOST||localhost,
user: process.env.DB_USER_NAME||myUserName ,
password: process.env.DB_PASSWORD||mypassword,
database: process.env.DB_NAME||mydb
});
con.connect((err) => {
if(err){
reject(err);
}
resolve(con);
});
})
}
module.exports.closeDbConnection =(con)=> {
con.destroy();
}
Step2: For Router.js I am import the db connection and handle the promise
const router = require('express').Router();
const {stablishedConnection,closeDbConnection} =require('../db/dbConnection');
router.get('/user/:sId/:userId',function(req,res){
stablishedConnection()
.then((db)=>{
console.log("Db connection stablished");
db.query(`select * from user WHERE sent_id=${req.params.sId} AND user_id=${req.params.userId}`, null, function (err,data) {
if (!data) {
res.status(200).json({sucess:false,err});
}else{
res.status(200).json({sucess:true,data});
closeDbConnection(db);
console.log("Db Connection close Successfully");
}
})
}).catch((error)=>{
console.log("Db not connected successfully",error);
});
});
router.get('/sen/:userId',function(req,res){
stablishedConnection()
.then((db)=>{
console.log("Db connection stablished");
db.query(`select * from sen WHERE user_id=${req.params.userId}`, null, function (err,data) {
if (!data) {
res.status(200).json({sucess:false,err});
}else{
res.status(200).json({sucess:true,data});
closeDbConnection(db);
console.log("Db Connection close Successfully");
}
})
}).catch((error)=>{
console.log("Db not connected successfully",error);
});
});
router.get('/language',(req,res)=>{
stablishedConnection()
.then((db)=>{
console.log("Db connection stablished");
db.query("select * from language", null, function (err,data) {
if (!data) {
res.status(200).json({sucess:false,err});
}else{
res.status(200).json({sucess:true,data});
closeDbConnection(db);
console.log("Db Connection close Successfully")
}
})
}).catch((error)=>{
console.log("Db not connected successfully",error);
});
})
module.exports = router;
This is perfectly run If you want to create and close connection at every query ..
I solved this problem like this:
let connection = mysql.createConnection(DB_CONFIG);
function runDBQuery() {
const disconnected = await new Promise(resolve => {
connection.ping(err => {
resolve(err);
});
});
if (disconnected) {
connection = mysql.createConnection(DB_CONFIG);
}
... use actual connection
}