我们有一个 Node.js 应用程序,它通过 pg-promise 连接到 Postgres 11 服务器 - 所有进程都在 Docker 容器中的单个云服务器上运行。
有时我们会遇到应用程序不再做出反应的情况。
The last time this happened, I had a little time to check the db via pgadmin and it showed that the connections were idle in transaction
with statement BEGIN
and an exclusive lock of virtualxid
我认为情况是这样的:
- 应用程序已通过发送
BEGIN
sql命令到数据库
- 数据库收到此命令并启动一个新事务,从而获得模式的排他锁
virtualxid
- 现在数据库等待应用程序发送下一条语句(直到它收到
COMMIT
or ROLLBACK
) - 然后它会释放模式的独占锁virtualxid
- 但由于某种原因,它没有得到更多的陈述:
我认为 node.js 事件循环被阻止 - 因为当时,当我们看到这些锁时,node.js 应用程序不再记录语句。但网络服务器仍然收到请求并报告一些upstream timed out
要求。
这有意义吗(我真的不确定2.和3.)?
为什么所有交易一开始都会被阻塞?这只是巧合还是显示的 SQL 可能是错误的?
顺便说一句:在这个answer https://stackoverflow.com/a/44908655/1041641我发现,我们可以设置事务中空闲会话超时 https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT这样这些事务将在超时后被释放 - 这很好,但我尝试了解导致此问题的原因。
交易根本不阻塞。数据库正在等待应用程序发送下一条语句。
事务 ID 上的锁只是事务相互阻塞的一种技术,即使它们没有争用表锁(例如,如果它们正在等待行锁):每个事务都拥有自己的排他锁事务 ID,如果它必须等待并发事务完成,它可以只请求对该事务 ID 的锁定(并被阻止)。
如果所有事务都像这样,那么锁一定位于应用程序中的某个位置;不涉及数据库。
当查找数据库中阻塞的进程时,请查找以下行:pg_locks
where granted
是假的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)