Knex:获取连接超时

Knex: Timeout acquiring a connection

从今天开始,当我尝试使用 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?

这发生在我从事了一年的项目中,没有任何问题。为了找出问题所在,我创建了一个包含 table 的新数据库。当运行宁以下代码行时,我得到同样的错误:

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

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

原来是节点 v14 的问题。当我使用 v13 或更早版本时它可以工作。

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

问题

Nodejs V14 进行了一些影响 pg 模块的重大更改!这使得它直接在 connect() call.

处退出

降级到v13就知道了! (我称之为 v14 地狱)!这是以前的解决方案!

pg v8.0.3.

中编写了 pg 修复程序

修复 v14

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

npm install pg@latest --save

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

v14 中发生了什么

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

节点V14! api 发生了一些重大变化!也改变了很多东西!包括 Openssl 版本!

对于 postgres!还有pg模块!问题如 comment per this thread:

中所述

The initial readyState (a private/undocumented API that

pg uses) of net.Socket seems to have changed from 'closed' to 'open' in Node 14.

It’s hard to fix with perfect backwards compatibility, but I think I have a patch that’s close enough.

并且根据这个 PR!

您可以在this diffing

中看到变化

总之如前所述! onReady 的 api 更改为 net.Socket ! 实施的解决方案是根本不使用 onReady!

并且按照这个

Connection now always calls connect on its stream when connect is called on it.

在旧版本中,仅当套接字处于 closed 状态时才调用连接! readyState 用法已消除!

勾选this line

你懂的!

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

Nodejs v14 相关变化

因为我想看看变化发生在哪里!给你

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

也可以查看更改日志:

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

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

还要提一下重大变化!使 pg 使进程在 connect() call 处退出。这就是它退出的原因!日志记录是有待观察的! 更详细的这个!这是怎么回事! Sequelize 有 postgres 方言实现!哪个用pg!还有pg客户端!创建连接!该连接有一个 connect 事件!当它连接时发出它!并且由于节点 v14 将流的行为更改为以打开开始!流连接被跳过!由于 readyState 检查(预期关闭但它变成了打开!)!并且流被视为已连接(否则阻止)!哪里不是! connect 事件直接发出!当那发生!客户端将调用连接对象的 requestSsl()startup() 方法!两者都会调用 this._stream.write。因为流没有连接!发生错误!这个错误不是catch!然后sequelize driver中的promise!将悬而未决!然后事件循环变空了! Nodejs 默认行为只是退出!

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

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

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

我刚刚使用 npm install pg@latest --save 升级了我的 psql,我的 knex 现在可以正常工作了。

事实上,这个错误可能是由很多问题引起的,今天我在上下滚动了无数个类似的线程无济于事后,艰难地找到了一个新的。

设置池时,knex 允许我们选择性地注册 afterCreate 回调,如果添加了此回调,则必须调用作为传递的 done 回调您注册的回调的最后一个参数,否则将无法获取连接导致超时。

.....
    pool: {
      afterCreate: (conn, done) => {
        // .... add logic here ....
        // you must call with new connection
        done(null, conn);
      },
    }
.....
"express": "^4.16.2",
"knex": "^0.14.2",
"objection": "^2.1.3",
"pg": "^8.0.3",

and npm install

我解决了我的问题(第 4 天结束)