Programming

[MariaDB / Node.js] retrieve connection from pool timeout after 에러

stein 2021. 5. 30. 21:49

MariaDB + Node.js + express.js 를 사용하여 API서버 - DB서버를 사용하고 있었다. 그런데 한 번씩 API 서버에서 DB서버로 query를 전달하지 못하는 현상이 발생했다.

API 서버에서 띄워주는 에러

conn = await pool.getConnection();

pool.getConnection에서 10초동안 connection을 반환하지 않았고, 이 시간이 설정되어있는 acquireTimeout을 넘어가서 에러를 띄우는 것이었다.

Pool의 구조 [https://mariadb.com/kb/en/connector-nodejs-promise-api/#connection-api]

pool.on("acquire", (conn) => {
  console.log(`acquire ${conn.threadId} has been acquire in pool`);
  console.log("acquire pool.activeConnections()", pool.activeConnections());
  console.log("acquire pool.totalConnections()", pool.totalConnections());
  console.log("acquire pool.idleConnections()", pool.idleConnections());
  });
pool.on("release", (conn) => {
  console.log(`connection ${conn.threadId} has been release in pool`);
  console.log("release pool.activeConnections()", pool.activeConnections());
  console.log("release pool.totalConnections()", pool.totalConnections());
  console.log("release pool.idleConnections()", pool.idleConnections());
  });

그래서 위의 코드를 통해서 pool에 연결된 connection들의 상태를 확인해보니, acquire횟수보다 release의 횟수가 적은것을 확인했고, release되는 threadId 값이 중복될 때가 있었다. (중복되면 idleConnections숫자와 totalConnections의 숫자가 같이 올라간다). 결국 activeConnections의 값이 totalConnection의 값과 같아질 때, pool은 더이상 getConnection요청에 connection을 반환해 줄 수 없게 된 것이다.

 

그래서 conn.end(), conn.release(), conn.destroy().... 등등 계속해서 삽질을 하다, 공식 사이트로 가서 코드를 확인했다.

https://mariadb.com/kb/en/getting-started-with-the-nodejs-connector/

async function asyncFunction() {
  let conn;
  try { conn = await pool.getConnection();
    const rows = await conn.query("SELECT 1 as val");
    console.log(rows);
    //[ {val: 1}, meta: ... ] const res = await conn.query("INSERT INTO myTable value (?, ?)", [1, "mariadb"]);            console.log(res);
    // { affectedRows: 1, insertId: 1, warningStatus: 0 } } catch (err) {
    throw err;
  } finally {
    if (conn) return conn.end();
  }
}

딱 한 줄이 달랐는데 바로,

let conn;

이었다.

 

아니... 그러면 왜 conn을 선언하지 않아도 작동했던 것인가...

 

conn 변수를 선언해 주니, 중복된 threadId로 release를 하거나, 누락되던 사항들이 깔끔하게 사라졌다.

 

이 문제로 힘들어 하시는 분이 혹시 계신다면, 본문이 도움이 되었으면 한다.

 

+ ps. 공식문서로 개발하자. 블로그 말고.