PostgreSQL 异常:“发送到后端时发生 I/O 错误”

问题描述 投票:0回答:11

我正在测试一些处理网站注册的代码。 java代码如下(摘录):

if (request.getParameter("method").equals("checkEmail")){
            String email= request.getParameter("email");
            ResultSet rs =null;
            PreparedStatement ps = db.prepareStatement(query);
            ps.setString(1, email);
            rs = ps.executeQuery();             
            if(rs.next()){ 
                            //email already present in Db 
            } else {
                            //proceed with registration.....

大多数情况下,进程执行时没有任何问题,但我遇到间歇性问题,由于与数据库的连接正在关闭,因此进程失败。每次失败时,它都会在同一点失败 - 当运行上面的准备好的语句时(它明显检查正在提交的电子邮件是否已经在数据库中)。

Postgres 的版本是 8.1.23

任何帮助或建议表示赞赏。 Stacktrace 如下(编辑:有时 Stacktrace 说是由 Stream Closed 引起的,有时是 Socket Closed 引起的,如下所示):

13:53:00,973 ERROR Registration:334 - org.postgresql.util.PSQLException: An I/O error occured while sending to the backend.

  at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:283)
  at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479
  at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
  at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271)
  at Registration.doPost(Registration.java:113)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
  at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:567)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
  at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
  at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
  at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:769)
  at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:698)
  at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:891)
  at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
  at java.lang.Thread.run(Thread.java:595)

Caused by: java.net.SocketException: Socket closed

  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:259)
  at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1620)
  at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    ... 22 more      
java postgresql io
11个回答
25
投票

我在 PostgreSQL 8.4 中遇到了相同的异常,但我连接到同一主机上的本地数据库。原因是连接不再有效,所以我需要再次打开它。

postgresql.org 上有一张ticket,其中有相关主题。他们的答案非常相似,只需捕获异常并重新打开连接


10
投票

我怀疑您的应用程序和数据库位于不同的计算机上,并且中间有一个(状态)防火墙。我的猜测是,防火墙在连接打开一定时间(可能没有流量)后会断开连接。连接池在向您提供断开的连接之前无法检测到这一点。

唯一让我怀疑的是,它总是发生在代码中的同一位置,但如果这是新会话(或类似的东西)中的第一个数据库查询,那么它总是出现在同一位置并不是不可想象的.


7
投票

我也遇到了同样的异常。

就我而言,由于某些查询大量使用内存,我的数据库正在重新启动。这就是为什么我在数据库重新启动期间收到该错误。

解决方案:我优化了我的查询。


1
投票

我在测试中遇到了同样的问题,但原因是在创建PreparedStatement和调用executeUpdate方法之间调用nextSequenceId,使用相同的Connection对象。 我的解决方案是将 nextSequenceId 的调用移到方法的顶部,问题就消失了。


1
投票

我有同样的问题并解决了我的更改是其中任何一个:

  • 您的查询非常大,例如:

    SELECT * FROM 'Table' WHERE id in ?param

param
是一个很大的列表。

  • 您的结果非常大(例如超过 4 GIG)

1
投票

我们在 Docker 容器中使用 PostgreSQL 13.5,并且有相同的异常。将容器的内存大小加倍即可解决问题。


0
投票

如果您使用连接池,您可以设置一个测试查询,例如“SELECT 1” - 这将有助于确保池中的连接在执行查询之前已准备好。 Spring Boot JPA - 配置自动重新连接

org.apache.commons.dbcp.BasicDataSource 示例:

 basicDataSource.testOnBorrow = true
 basicDataSource.validationQuery = "SELECT 1"

我最常注意到这个问题是在应用程序静置后没有采取太多操作,但我认为它通常会在一天中发生,如上所述。


0
投票

我遇到了同样的问题,我重新启动了 docker 服务,解决了上面所说的问题,可能是 PGSQL 的内存泄漏/问题。

org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.

docker-compose down

docker-compose up -d


0
投票

我遇到了同样的问题(Postgresql 13)。该错误消息表明存在连接问题,但这具有误导性。我编辑了一个 plpython3u Python 函数,该函数后来产生了运行时错误,进而产生了“发送到后端时出现 I/O 错误”。当Windows Python相关的环境变量被更改并导致Python无法正常运行时,也会出现类似的错误。


0
投票

我遇到了同样的错误,这对我来说没有意义,所以我在一些文章中读到这个问题可能是数据库连接中的防火墙问题。对我有用的是更改我的 quarkus 项目的 http 端口,它是 8181,然后我更改为 9090,它就可以工作了!


-4
投票

这在很大程度上适用于开发环境。

如果有人最近遇到此问题并且同时在 Ubuntu 19.10 下使用 docker v19.03.5,它往往会中断某些网络管理器配置的网络连接。我还没有机会详细调试这个问题,但如果您遇到这个问题,我强烈建议您尝试一下

$ sudo service docker stop

并再试一次连接。

对我来说就像魅力一样。

© www.soinside.com 2019 - 2024. All rights reserved.