简体   繁体   English

已授予所有锁的 postgresql“事务空闲”

[英]postgresql "idle in transaction" with all locks granted

A very simple delete (by key) on a small table (700 rows) every now and then stays "idle in transaction" for minutes (takes milliseconds usually) even though all the locks are marked as "granted".一个非常简单的删除(键)小表(700 行),然后保持“空闲事务”几分钟(通常需要几毫秒),即使所有锁都标记为“已授予”。

What can I do to pinpoint what causes it?我能做些什么来查明是什么原因造成的? I'm using this select:我正在使用这个选择:

  SELECT a.datname,
     c.relname,
     l.transactionid,
     l.mode,
     l.GRANTED,
     a.usename,
     a.waiting,
     a.query, 
     a.query_start,
     age(now(), a.query_start) AS "age", 
     a.pid 
FROM  pg_stat_activity a
 JOIN pg_locks         l ON l.pid = a.pid
 JOIN pg_class         c ON c.oid = l.relation
ORDER BY a.query_start;

which shows a lot of "RowExclusiveLock"s but all are granted... so I don't see what is causing this spikes of delays.它显示了很多“RowExclusiveLock”,但都被授予了......所以我看不出是什么导致了这种延迟高峰。

This is a problem of the application server. 这是应用程序服务器的问题。

Sessions are in state "idle in transaction" when the application does not end the transaction with COMMIT or ROLLBACK . 当应用程序未使用COMMITROLLBACK结束事务时,会话处于“事务中空闲”状态。 This is to be considered a bug in the application. 这被认为是应用程序中的错误。

The locks remain (and are of course granted, otherwise the session could not be idle) until the transaction ends. 在事务结束之前,锁保持(并且当然被授予,否则会话不能空闲)。

From PostgreSQL 9.6 on, you can set the parameter idle_in_transaction_session_timeout to terminate such transactions automatically with a ROLLBACK , but that is a band-aid to avoid problems on the database rather than a solution. 从PostgreSQL 9.6开始,您可以设置参数idle_in_transaction_session_timeout以使用ROLLBACK自动终止此类事务,但这是一个创可贴以避免数据库上的问题而不是解决方案。

It could also be due to a combination of 1) exhaustion of a connection pool 2) Transactions within transactions 3) Implicit postgres transactions within transactions.这也可能是由于 1) 连接池耗尽 2) 事务中的事务 3) 事务中的隐式 postgres 事务的组合。 This article opened my eyes on this issue https://www.birdie.care/blog/birdie-engineering-update这篇文章让我对这个问题大开眼界 https://www.birdie.care/blog/birdie-engineering-update

This explains why there are no deadlocks in the database itself.这就解释了为什么数据库本身没有死锁。 It's only because app's connection pool ceiling is reached.这只是因为达到了应用程序的连接池上限。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM