nodejs mysql 오류 : 연결이 끊어졌습니다. 서버가 연결을 닫았습니다.


89

mysql 노드를 사용할 때 서버에 의해 TCP 연결이 종료되었다는 오류가 12:00에서 2:00 사이에 나타납니다. 다음은 전체 메시지입니다.

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)

솔루션은 . 그런데 이렇게 해보면 문제도 나옵니다. 지금은 어떻게해야할지 모르겠습니다. 누구든지이 문제를 충족합니까?

솔루션을 따르는 방법은 다음과 같습니다.

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

답변:


160

이 코드 를 사용 하여 서버 연결 해제를 처리하십시오.

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

귀하의 코드에서 나는 부품이 누락되었습니다. connection = mysql.createConnection(db_config);


네, 이거해볼 게요. 하지만이 siutation 시뮬레이션 수있는 방법
jackieLin

1
팁 : 모든 것이 잘 작동하는지 확인하기 위해 mysql 서비스를 다시 시작하여 재 연결을 테스트하고 있습니다.
kriskodzi 2014 년

2
@jackieLin ubuntu sudo 서비스 mysql restart에서 mysql 서비스를 다시 시작하여 상황을 시뮬레이션 할 수 있습니다.
igor

1
@ user3073745 감사합니다.이 문제는 다시 시작하여 해결되었습니다
jackieLin

1
노드 8. *, npm 5.6.0 및 mysql : 5.7에서 완벽하게 작동합니다 ... 감사합니다 !!
JRichardsz

47

이 메커니즘에 대한 원래 사용 사례를 기억하지 않습니다. 요즘에는 유효한 사용 사례를 생각할 수 없습니다.

클라이언트는 연결이 끊어진시기를 감지하고 연결을 다시 만들 수 있어야합니다. 프로그램 로직의 일부가 동일한 연결을 사용하여 실행되는 것이 중요하다면 트랜잭션을 사용하십시오.

tl; dr; 이 방법을 사용하지 마십시오.


실용적인 해결책은 MySQL이 연결을 유지하도록하는 것입니다.

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

연결 상태를 인식하는 방식으로 코드를 구성 할 필요가 없기 때문에 연결 풀 및 연결 해제 처리보다이 솔루션을 선호합니다. 5 초마다 쿼리를 작성하면 연결이 활성 상태로 유지되고 PROTOCOL_CONNECTION_LOST발생하지 않습니다.

또한이 방법을 사용하면 다시 연결하는 대신 동일한 연결을 유지하고 있습니다. 이것은 중요하다. 스크립트에 의존 LAST_INSERT_ID()하고 mysql 연결이 자신도 모르게 재설정 된 경우 어떻게 될지 생각해보십시오 .

그러나 이렇게하면 연결 시간 초과 ( wait_timeoutinteractive_timeout)가 발생하지 않을 뿐입니다 . 예상대로 다른 모든 시나리오에서는 실패합니다. 따라서 다른 오류를 처리해야합니다.


1
궁금한 점이 있으면 해당 DB 쿼리를 어디에 넣을까요? nodejs 서버의 맨 아래에 있습니까? 유일한 문제는 mysql을 사용하여 사용자를 한 번만 인증 한 다음 내 RPG 게임의 임시 사용자 개체에 데이터를 저장한다는 것입니다. 오늘이 mysql closed error가 무작위로 발생하는 이유를 모르겠습니다. 연결도 제대로 닫고 있습니다.
NiCk Newman

1
데이터베이스에 연결하고 필요에 따라 연결을 끊어야합니다. 이 솔루션은 지속적으로 실행되고 데이터베이스 연결을 항상 활용하는 서비스를위한 것입니다.
Gajus 2015 년

1
코드가 설명 된 패턴 ( gist.github.com/gajus/5bcd3c7ec5ddcaf53893 과 유사 ) 을 따르고 있다는 점을 감안할 때 어느 쪽도 들리지 않을 것 입니다. 이것이 수천 개의 쿼리 중 한두 번만 발생하면 연결 문제, 서버 과부하 또는 그 라인을 따라 무언가가 있다고 가정합니다.
Gajus

2
그것은 아마도 최악의 제안이었을 것입니다! 연결이 끊기지 않도록 쿼리로 데이터베이스를 망치라고 제안하는 사람? 100 명이 이렇게하면 어떻게 되나요? 또는 왜 10,000 개가 아닌지, 앱이 주목하는 경우 스레드는 약한 코드가 중단되지 않도록 스레드를 호깅하지 않고 MYSQL 스레드 풀로 반환해야합니다.이 경우 이러한 이벤트가 발생하면 다시 연결하는 기능을 구현합니다. ! 믿기지가 않네요. FB가 당신을 수석 아키텍트로 두지 않았다는 사실에 정말 감사합니다 !!
Patrik Forsberg

2
이 접근 방식을 권장하지 않음을 반영하여 답변을 업데이트했습니다. Patrik의 머리에 감사드립니다.
Gajus



1

각 쿼리에서 연결을 만들고 파괴하는 것은 복잡 할 수 있습니다. MySQL 대신 MariaDB를 설치하기로 결정했을 때 서버 마이그레이션에 약간의 골칫거리가있었습니다. etc / my.cnf 파일에서 어떤 이유로 wait_timeout 매개 변수의 기본값은 10 초입니다 (지속성을 구현할 수 없음). 그런 다음 솔루션은 28800, 즉 8 시간으로 설정되었습니다. 글쎄, 나는이 "güevonada"로 누군가를 돕길 바랍니다 ... 나의 나쁜 영어에 대해 실례합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.