web-dev-qa-db-fra.com

nodejs mysql Erreur: connexion perdue Le serveur a fermé la connexion

lorsque j'utilise le noeud mysql, une erreur se produit entre midi et deux heures lorsque la connexion TCP est interrompue par le serveur. Ceci est le message complet:

Error: Connection lost: The server closed the connection.
at Protocol.end (/opt/node-v0.10.20-linux-x64/IM/node_modules/mysql/lib/protocol/Protocol.js:73:13)
at Socket.onend (stream.js:79:10)
at Socket.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)

Il y a la solution . Cependant, après avoir essayé de cette façon, le problème apparaît également. maintenant je ne sais pas comment faire. Est-ce que quelqu'un rencontre ce problème?

Voici la façon dont j'ai écrit suivre la solution:

    var handleKFDisconnect = function() {
    kfdb.on('error', function(err) {
        if (!err.fatal) {
            return;
        }
        if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
            console.log("PROTOCOL_CONNECTION_LOST");
            throw err;
        }
        log.error("The database is error:" + err.stack);

        kfdb = mysql.createConnection(kf_config);

        console.log("kfid");

        console.log(kfdb);
        handleKFDisconnect();
    });
   };
   handleKFDisconnect();
63
jackieLin

Essayez d’utiliser ce code pour gérer la déconnexion du serveur:

var db_config = {
  Host: 'localhost',
    user: 'root',
    password: '',
    database: 'example'
};

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();

Dans votre code, il me manque les parties après connection = mysql.createConnection(db_config);

115
CloudyMarble

Je ne me souviens pas de mon cas d'utilisation d'origine pour ce mécanisme. De nos jours, je ne peux penser à aucun cas d'utilisation valable.

Votre client doit pouvoir détecter le moment où la connexion est perdue et vous permettre de recréer la connexion. S'il est important qu'une partie de la logique du programme soit exécutée à l'aide de la même connexion, utilisez des transactions.

tl; dr; Ne pas utiliser cette méthode.


Une solution pragmatique consiste à forcer MySQL à maintenir la connexion en vie:

setInterval(function () {
    db.query('SELECT 1');
}, 5000);

Je préfère cette solution au pool de connexion et à la gestion de la déconnexion, car elle ne nécessite pas de structurer votre code de manière à prendre en compte la présence de la connexion. Effectuer une requête toutes les 5 secondes garantit que la connexion restera active et que PROTOCOL_CONNECTION_LOST ne se produira pas.

De plus, cette méthode garantit que vous gardez la même connexion vivante , par opposition à la reconnexion. C'est important. Pensez à ce qui se produirait si votre script reposait sur LAST_INSERT_ID() et que la connexion mysql avait été réinitialisée sans que vous en soyez conscient.

Cependant, cela garantit uniquement que le délai de connexion (wait_timeout et interactive_timeout) ne se produit pas. Comme prévu, il échouera dans tous les autres scénarios. Par conséquent, assurez-vous de gérer les autres erreurs.

34
Gajus

Pour simuler une connexion perdue, essayez

connection.destroy();

Plus d'informations ici: https://github.com/felixge/node-mysql/blob/master/Readme.md#terminating-connections

3
Simon Fearby

La création et la destruction des connexions dans chaque requête peuvent être compliquées, j'ai eu quelques problèmes avec une migration de serveur lorsque j'ai décidé d'installer MariaDB à la place de MySQL. Pour une raison quelconque, dans le fichier etc/my.cnf, le paramètre wait_timeout avait une valeur par défaut de 10 secondes (la persistance ne pouvait donc pas être mise en œuvre). Ensuite, la solution a été définie en 28800, soit 8 heures. Eh bien, j'espère aider quelqu'un avec cette "güevonada" ... excusez-moi pour mon mauvais anglais.

0
Aleks Towers