PostgreSQL空闲事务诊断和读取pg_locks

时间:2010-07-22 20:03:54

标签: postgresql

设置:多个Web服务器,运行mod_wsgi,Apache和pgbouncer,它们连接到运行Postgres 8.3.6的共享数据库。应用程序正在运行Django。

我们所看到的:'闲置在交易中'查询数据库,这些数据库已经存在了很长时间。为了看到它们,我会运行这样的事情:

SELECT query_start, procpid, client_addr, current_query FROM pg_stat_activity
WHERE query_start < NOW() - interval '5 minutes';

大多数结果当然只是IDL连接,pgbouncer保持开放使用,但有时候会有这些旧的'IDLE in transaction'查询。我知道这意味着有一个查询事务正在等待某事,或者有一个BEGIN但没有达到COMMIT或ROLLBACK的东西。

我的下一步是尝试使用pg_locks来确定进程正在等待的内容:

select pg_class.relname, pg_locks.transactionid, pg_locks.mode,
       pg_locks.granted as "g", pg_stat_activity.current_query,
       pg_stat_activity.query_start,
       age(now(),pg_stat_activity.query_start) as "age",
       pg_stat_activity.procpid 
from pg_stat_activity,pg_locks
left outer join pg_class on (pg_locks.relation = pg_class.oid)  
where pg_locks.pid=pg_stat_activity.procpid
and pg_stat_activity.procpid = <AN IDLE TRANSACTION PROCESS>
order by query_start;

很多时候,我得到的结果是这样的:

 relname | transactionid |      mode       | g |     current_query     |         query_start          |       age       |  client_addr   | procpid 
---------+---------------+-----------------+---+-----------------------+------------------------------+-----------------+----------------+---------
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | ExclusiveLock   | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
         |               | AccessShareLock | t | <IDLE> in transaction | 2010-07-22 15:33:11.48136-04 | 00:23:35.029045 | 192.168.100.99 |    1991
(10 rows)

我不知道怎么读这个(我猜它源于没有真正理解pg_locks)。没有relname,所以它说什么都没有等待?我认为,如果被授予“真实”,它就有了锁定。由于所有这些结果都被授予,pg_locks是否显示了它所拥有的锁而不是它正在等待的锁?

现在我正在通过重启Apache来解决这个问题,这似乎会破坏交易松散,但显然这不是一个真正的解决方案。我正在寻找Postgres给我一个关于在哪里寻找这个问题的地方,特别是因为Django应该自动管理它的连接和交易。

1 个答案:

答案 0 :(得分:3)

对于Django,此条目详细说明了您看到此问题的原因:

Threaded Django task...

我在这里说“具体”是因为真正的问题是web框架/驱动程序/ ORM在基于事务的模式下一直工作(有时候在每个freakin'ELEL查询之后调用回滚)它们应该真正运行在自动提交模式,仅在需要的基础上处理交易需求。 Apache :: Sessions PostgreSQL持久性模块是一场灾难(至少在几年前),因为它只在垃圾收集时关闭了事务。糟糕!