Postgresql 8.4 带有 JDBC 访问时偶尔出现挂起问题

12

我有一个非常依赖数据库的应用程序,它运行多个小时并使用多个线程,所有线程都通过JDBC与PostgreSQL通信。我看到的症状是偶尔(每次“运行”一到三次)会出现一个或多个被卡住的JDBC连接,它们似乎在等待来自数据库的响应,但似乎永远等不到。以下是线程转储:

"Thread-4367355" daemon prio=6 tid=0x04920c00 nid=0x1e88 runnable [0x04bef000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:135)
    at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:104)
    at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73)
    at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:255)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1165)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
    - locked <0x2c023e10> (a org.postgresql.core.v3.QueryExecutorImpl)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:337)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:329)

除非很多时候只有一个线程被卡住,否则我会认为这是某种锁定问题。 我见过的其中一个查询处于这种状态,是REINDEX,因此可能查询需要相当长的时间。 为了寻找解决方案,我将JDBC驱动程序从8.4升级到9.1,但问题仍然存在。 Postgresql日志中也没有异常情况。 除了使用pg_locks之外,还有什么进一步诊断的想法吗?


你解决问题了吗?我们在9.1上也遇到了同样的“卡顿”问题。 - Jan Hoeve
我遇到了同样的问题,Postgresql 8.4,JDBC驱动程序9.1。查询是一个复杂的删除操作。服务器上的进程开始使用100%的CPU,然后突然降至0%,并永远停留在0%。客户端线程就像上面一样被卡住了。 - Bruno Medeiros
请注意,如果程序卡住并显示“BLOCKED waiting for object XXX”,那可能意味着您的Postgres连接正在被多个线程使用[当然,在这种情况下不是这样,只是作为一个提示]。 - rogerdpack
1个回答

1

你可以尝试显而易见的方法:将PostgreSQL本身更新到9.1版本。
你也可以记录所有长时间运行的语句,这可能会给你一些线索。

Set log_min_duration_statement = 2000

或者任何适合您的阈值。
我不知道如何解释线程转储,但这一行看起来很奇怪:

  • locked <0x2c023e10> (a org.postgresql.core.v3.QueryExecutorImpl)

什么是锁定?您是否注意到它拼错了“at a org.postgresql.cor...”?这是复制粘贴的产物还是原始消息?如果是,可能有助于找到其来源。


1
locked<0x2c023e10> 表示该方法已获取了一个锁,该锁是 org.postgresql.core.v3.QueryExecutorImpl 对象。而十六进制则是该锁的地址? - crybird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接