Reproduce MySQL error: The server closed the connection (node.js)

nflacco picture nflacco · Oct 22, 2012 · Viewed 20.1k times · Source

I'm trying to reproduce a MySQL error I'm seeing in my node.js app on EC2 with the node mysql library:

Connection lost: The server closed the connection.

I am unable to reproduce the error locally- killing the database is handled just fine by my code- it just rechecks every few seconds and reconnects to the db once it is restarted. On EC2, it happens around 4am Pacific, but the db is still up and running fine.

I'd like to

  1. Reproduce the crash with my local mysql
  2. Add whatever logic I need in my mysql helper module to handle this

Here's the error in my node.js app:

2012-10-22T08:45:40.518Z - error: uncaughtException date=Mon Oct 22 2012 08:45:40 GMT+0000 (UTC), pid=14184, uid=0, gid=0, cwd=/home/ec2-user/my-app, execPath=/usr/bin/nodejs, version=v0.6.18, argv=[/usr/local/bin/node, /home/ec2-user/my-app/app.js, --my-app], rss=15310848, heapTotal=6311392, heapUsed=5123292, loadavg=[0.0029296875, 0.0146484375, 0.04541015625], uptime=3238343.511107486, trace=[column=13, file=/home/ec2-user/my-app/node_modules/mysql/lib/protocol/Protocol.js, function=Protocol.end, line=63, method=end, native=false, column=10, file=stream.js, function=Socket.onend, line=80, method=onend, native=false, column=20, file=events.js, function=Socket.emit, line=88, method=emit, native=false, column=51, file=net.js, function=TCP.onread, line=388, method=onread, native=false], stack=[Error: Connection lost: The server closed the connection.,
at Protocol.end (/home/ec2-user/my-app/node_modules/mysql/lib/protocol/Protocol.js:63:13), at Socket.onend (stream.js:80:10), at Socket.emit (events.js:88:20), at TCP.onread (net.js:388:51)]

Here's my code (mysql helper module):

module.exports = function (conf,logger) {
  var mysql = require('mysql');

  var connectionState = false;
  var connection = mysql.createConnection({
    host: conf.db.hostname,
    user: conf.db.user,
    password: conf.db.pass,
    database: conf.db.schema,
    insecureAuth: true
  });

  function attemptConnection(connection) {
    if(!connectionState){
      connection = mysql.createConnection(connection.config);
      connection.connect(function (err) {
        // connected! (unless `err` is set)
        if (err) {
          logger.error('mysql db unable to connect: ' + err);
          connectionState = false;
        } else {
          logger.info('mysql connect!');
          connectionState = true;
        }
      });
      connection.on('close', function (err) {
        logger.error('mysqldb conn close');
        connectionState = false;
      });
      connection.on('error', function (err) {
        logger.error('mysqldb error: ' + err);
        connectionState = false;

        /*
        if (!err.fatal) {
          return;
        }
        if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
          throw err;
        }
        */
      });
    }
  }
  attemptConnection(connection);

  var dbConnChecker = setInterval(function(){
    if(!connectionState){
      logger.info('not connected, attempting reconnect');
      attemptConnection(connection);
    }
  }, conf.db.checkInterval);

  return connection;
};

Answer

Aley picture Aley · Jun 4, 2013

Check out mysql pool feature in node-mysql

var mysql = require('mysql');
var pool  = mysql.createPool({
  host     : 'example.org',
  user     : 'bob',
  password : 'secret'
});

pool.getConnection(function(err, connection) {
  // connected! (unless `err` is set)
  connection.end();
});