Исключение PSQLException: При отправке на сервер произошла ошибка ввода-вывода. … Вызвано: исключение java.io.EOFException

# #java #postgresql #google-cloud-sql

Вопрос:

Окружающая среда

База данных: Облачный SQL(Postgres) на GCP

Приложение: ServiceA (написано на java 8)

Ниже приведен упрощенный фрагмент кода, в котором происходит ошибка:

 for(String id: ids){
   int result = dao.getCountForId(id) // where the error is thrown
   if(result>0){
     ...
   }
}
 

Запрос, отправленный в Postgres:

 SELECT COUNT(*) FROM t WHERE id = ?
 

Выброс ошибки выглядит так, как показано ниже:

 xxxxx.postgres.PostgresRuntimeException: Failed get count for id 7dddfdsfdsewr345234sd.........
xxxx.postgres.PostgresRuntimeException: Failed get result for id ....
Caused by: org.PostgreSQL.util.PSQLException: An I/O error occurred while sending to the backend.
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:339) ~[app.jar:?]
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448) ~[app.jar:?]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369) ~[app.jar:?]
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:153) ~[app.jar:?]
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:103) ~[app.jar:?]
    at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source) ~[?:?]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_171]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_171]
    at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:428) ~[app.jar:?]
    at com.sun.proxy.$Proxy40.executeQuery(Unknown Source) ~[?:?]
Caused by: java.io.EOFException
    at org.postgresql.core.PGStream.receiveChar(PGStream.java:372) ~[app.jar:?]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2043) ~[app.jar:?]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:312) ~[app.jar:?]
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448) ~[app.jar:?]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369) ~[app.jar:?]
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:153) ~[app.jar:?]
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:103) ~[app.jar:?]
    at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source) ~[?:?]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_171]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_171]
    at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:428) ~[app.jar:?]
 

Эта ошибка произошла в производстве, когда количество идентификаторов было большим. Но я не могу реплицироваться в тестовой или локальной среде.

Попытки

Я думал, что причиной ошибки было много запросов, выданных из-за больших идентификаторов массивов, что привело к насыщению пулов соединений Postgres. Для проверки этой гипотезы я создал интеграционный тест, который насыщает пул соединений множеством запросов, как показано ниже(упрощенная версия):

 //FILE_PATH contains the input and expected output for the test
  @Test
    @FileParameters(value = FILE_PATH)
    public test(String taskId, int expected){
        int result = dao.getCountForId(id) 
        Assert.assertEquals(expected,result);
    }
 

Ошибка из насыщенного пула соединений с большим количеством запросов выглядит так, как показано ниже:

 org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
    at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:525) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:146) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:197) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:217) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.Driver.makeConnection(Driver.java:458) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.Driver.connect(Driver.java:260) ~[postgresql-42.2.14.jar:42.2.14]
    at java.sql.DriverManager.getConnection(DriverManager.java:664) ~[?:1.8.0_282]
    at java.sql.DriverManager.getConnection(DriverManager.java:247) ~[?:1.8.0_282]
    at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:98) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:83) ~[postgresql-42.2.14.jar:42.2.14]
 

Я ищу в журналах GCP ошибку org.PostgreSQL.util.PSQLException: FATAL: sorry, too many clients already , но не нашел никаких записей. Похоже, что эта ошибка не возникает.

Я буду признателен за любую помощь или рекомендации в решении этой проблемы.

С наилучшими пожеланиями, Рэндо.

Комментарии:

1. Найдите соответствующее сообщение об ошибке в файле журнала сервера для первой ошибки. Что касается второй ошибки, которую вы не найдете org.PostgreSQL.util.PSQLException в журнале сервера, то это украшение, добавленное клиентом.

2. Первая строка ошибки выглядит так, как показано ниже: io.dexi.postgres.PostgresRuntimeException: Failed get count for id 7dddfdsfdsewr345234sd