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
用法已消除!
你懂的!
取决于实施!许多事情可能会或不会受到这些核心变化的影响!
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 默认行为只是退出!
通过代码行可以看到步骤:
- Sequelize pg adapter will call pg client to create a connection and the promise
- pg client call connect on a connection object
- pg connection
connect()
call and emit connect
! Thinking the stream is connected because of V14 change
- pg client
connect
event catched and callback run! requestSsl()
or startup()
will be run
- 其中一个方法 get 运行 和
stream.write
将被调用 (requestSsl(), startup())
- 流错误(未捕获)
- Promise 在 sequelize postgres 适配器中!仍未解决!
- 事件循环为空 => 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 天结束)
从今天开始,当我尝试使用 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
.
修复 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
用法已消除!
你懂的!
取决于实施!许多事情可能会或不会受到这些核心变化的影响!
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 默认行为只是退出!
通过代码行可以看到步骤:
- Sequelize pg adapter will call pg client to create a connection and the promise
- pg client call connect on a connection object
- pg connection
connect()
call and emitconnect
! Thinking the stream is connected because of V14 change - pg client
connect
event catched and callback run!requestSsl()
orstartup()
will be run - 其中一个方法 get 运行 和
stream.write
将被调用 (requestSsl(), startup()) - 流错误(未捕获)
- Promise 在 sequelize postgres 适配器中!仍未解决!
- 事件循环为空 => 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 天结束)