2010-07-22 53 views
12

设置:运行mod_wsgi,Apache和pgbouncer的多个webservers,它们连接到运行Postgres 8.3.6的共享数据库。应用程序正在运行Django。PostgreSQL在事务诊断和读取中处于空闲状态pg_locks

我们所看到的:在闲置了很长时间的数据库中的“闲置交易”查询。为了能看到他们,我会遇到这样的事情:

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

大多数,当然结果是pgbouncer是保持开放使用只是空闲连接,但有时会有疑问,这些老字号“在交易IDLE” 。我知道这意味着有一个正在等待某事的查询事务,或者是有一个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

一个相当可能的原因,你没有看到任何relname是因为你连接到错误的数据库。运行查询的连接需要连接到关系所在的同一个数据库,否则将无法为您提供名称。我猜你是连接到“postgres”数据库,或者当运行查询时...... – 2010-07-23 11:20:01

回答

3

Django的明确,这个条目详细信息为什么你看到这个问题:

Threaded Django task...

我说“特别”在这里,因为真正的问题是所有的工作时间在一个事务中的web框架/司机/奥姆斯基于模式的模式(有时在每次freakin'SELECT查询之后调用回滚),当它们真的应该在自动提交模式下运行并且只在需要的时候处理事务的需要。 Apache :: Sessions PostgreSQL持久化模块是一场灾难(至少在几年前),因为它仅在垃圾收集时关闭事务。哎呀!

+0

据我所知,虽然有一个,他发现他只需要在计划的cron作业的上下文中手动关闭连接,即Django的连接关闭信号在请求完成时触发不涉及。这些空闲事务来自不运行任何cron /独立Django进程的Web服务器。 – KRH 2010-07-23 02:31:48

相关问题