PostgreSQL Idle In 事务诊断和读取pg_locks

标签 postgresql

设置:多个网络服务器,运行 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';

当然,大多数结果只是 pgbouncer 保持打开以供使用的 IDLE 连接,但有时会有这些旧的“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,所以它是说它在等待什么?我认为如果 granted 是“真实的”,它就有了锁。由于所有这些结果都已获得批准,pg_locks 是否向我展示了它拥有的锁而不是它正在等待的锁?

现在我正在通过重新启动 Apache 来“修复”这个问题,这似乎使事务变得松散,但显然这不是真正的解决方案。我正在寻找 Postgres 给我一个地方来解决这个问题,特别是因为 Django 应该自动管理它的连接和事务。

最佳答案

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

Threaded Django task...

我在这里说“具体”是因为真正的问题是 web 框架/驱动程序/ORM 一直在基于事务的模式下工作(有时在每个奇怪的 SELECT 查询之后调用回滚),而它们实际上应该在一个自动提交模式,仅按需处理交易需求。 Apache::Sessions PostgreSQL 持久化模块是一场灾难(至少在几年前),因为它只在被垃圾收集时才关闭事务。哎呀!

关于PostgreSQL Idle In 事务诊断和读取pg_locks,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3312929/

相关文章:

linux - 错误 : You must install at least one postgresql-client-<version> package

node.js - NodeJS Sequelize 制作主表降序示例

node.js - sequelize-auto TypeError : connection. query(...).on 不是函数

ruby-on-rails - JSONB 不适用于 Rails 5? JSON 字段以字符串形式返回

postgresql - 如何对 pg_index 执行更新

node.js - 使用事务时,查询中包含的子查询如何在 pg-promise 中工作?

java - Spring Boot JPA @ColumnDefault 在 PostgreSQL 上被错误解释 : ERROR: cannot use column reference in DEFAULT expression

sql - PostgreSQL autoicrementing id 是否可扩展?

postgresql - 在文本 Postgres 中找到 "'"

sql - 在postgres中将日期字段转换为多个字段的最快方法