Knex:获取连接超时

Fla*_*vio 5 postgresql node.js knex.js postgresql-12

从今天开始,当我尝试使用 knex.js 在本地连接到 postgres 数据库 (v 12) 时,出现以下错误。

Unhandled rejection TimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?
Run Code Online (Sandbox Code Playgroud)

这种情况发生在我已经工作了一年的项目上,没有出现任何问题。为了解决这个问题,我创建了一个包含一张表的新数据库。运行以下代码行时,我收到相同的错误:

const knex = require('knex');

const db = knex({
  client: 'pg',
  connection: 'postgresql://postgres:postgres@localhost/a_test',
  pool: {
    min: 0,
    max: 10,
  },
});

db.from('test_table')
  .select(['id'])
  .then(r => {
    console.log(r);
  });

Run Code Online (Sandbox Code Playgroud)

我不知道是什么原因造成的。几周前,一切都运行良好,在此期间我没有改变任何东西。我使用postgresapp在本地运行 postgres ,当我使用 连接到数据库时psql,一切正常。我有什么想法可以解决这个问题吗?

Moh*_*lal 11

问题

\n

Nodejs V14 做了一些影响pg模块的重大更改!这使得它直接退出connect() call

\n

降级到v13就知道了!(我称之为v14 HELL)!过去这是一个解决方案!

\n

pg 的修复已写入pg v8.0.3.

\n

修复 v14

\n

如果您正在使用postgres!使用nodejs v14及以上版本!确保使用pg该版本的驱动程序模块>=8.0.3驱动程序模块!并更好地升级到最新

\n
npm install pg@latest --save\n
Run Code Online (Sandbox Code Playgroud)\n

如果您不使用postgres!尝试更新您的数据库驱动程序!可能是一样的吧!也尝试使用nodejs V13。确认是同样的问题!(V14 地狱

\n

v14 中发生了什么

\n

如果像我一样你想知道细节以及发生了什么!?

\n

使用节点 V14!API 发生了一些重大变化!还有很多东西都改变了!包括Openssl版本!

\n

对于postgres!还有pg模块!问题如该线程评论中所述:

\n
\n

初始的readyState(一个私有/未记录的API,

\n

在 Node 14 中,net.Socket 的 pg 使用)似乎已从“封闭”更改为“开放”。

\n

它\xe2\x80\x99s 很难修复并具有完美的向后兼容性,但我想\n我有一个\xe2\x80\x99s 足够接近的补丁。

\n
\n

根据此PR

\n

你可以看到这个差异的变化

\n

简而言之,如上所述!onReady 的 api 发生了变化net.Socket!\n并且实现的解决方案是根本不使用 onReady!

\n

并且根据这个

\n
\n

现在,当在其上调用 connect 时,Connection 始终会在其流上调用 connect。

\n
\n

在旧版本中,仅当套接字处于打开closed状态时才调用 connect!readyState使用被消除!

\n

检查这一行

\n

你能明白!

\n

取决于实施!许多事情可能会或不会受到这些核心变化的影响!

\n

Nodejs v14相关变更

\n

因为我想看看变化发生在哪里!干得好

\n

https://github.com/nodejs/node/pull/32272

\n

人们也可以检查更改日志:

\n

https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md

\n

详细原因+退出并且没有日志记录错误

\n

还要提一下重大变化!使pg进程在 处退出connect() call。这就是它退出的原因!并且可以看到日志记录!\n对此有更多详细信息!这是怎么发生的!Sequelize 有 postgres 方言实现!哪个用pg!还有pg客户端!创建连接!连接有一个connect事件!当它连接时它会发出它!而且因为节点 v14 将流的行为更改为以 open 开头!流连接被跳过!因为readyState检查(预计是关闭的,但它变成了开放!)!并且流被视为已连接(否则为块)!哪里不是!并且connect事件是直接发出的!当这种情况发生时!客户端要么调用连接对象的方法requestSsl(),要么调用startup()连接对象的方法!双方都会打电话this._stream.write。因为流没有连接!发生错误!这个错误没有被catch!那么续集驱动程序中的承诺!将一直悬而未决!然后事件循环变空!Nodejs 默认行为只是退出!

\n

您可以通过代码行看到该步骤:

\n\n

为什么nodejs退出(未解决的承诺)

\n

https://github.com/nodejs/node/issues/22088

\n

节点退出时没有错误并且不等待承诺(事件回调)

\n

当 Promise 永远无法解决时会发生什么?

\n


Mik*_*stö 5

看起来应该使用 Node 14 较新的 (>8.0.3) pg 驱动程序版本。https://github.com/knex/knex/issues/3912