# #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