JDBC-клиент Postgres застревает при чтении из сокета - PullRequest
0 голосов
/ 11 мая 2018

У меня есть база данных PostGIS и клиент, построенный поверх HikariCP, для чтения данных из базы данных. Мой клиент может читать данные без проблем на некоторых машинах . Однако на некоторых других машинах клиент застревает и не может прочитать какие-либо исключения из-за превышения времени ожидания сокета.

MyClass:120 - Failed to execute HikariProxyPreparedStatement@2091541230 wrapping <my-query>.
org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:332)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:155)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:118)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
    ...
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:140)
    at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:109)
    at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:67)
    at org.postgresql.core.PGStream.receiveChar(PGStream.java:293)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1947)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:306)
    ... 32 more

ProxyConnection:161 - HikariPool-1 - Connection org.postgresql.jdbc.PgConnection@1aafd32f marked as broken because of SQLSTATE(08006), ErrorCode(0)
org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:332)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:155)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:118)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
    ...
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:140)
    at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:109)
    at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:67)
    at org.postgresql.core.PGStream.receiveChar(PGStream.java:293)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1947)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:306)
    ... 31 more

Прежде чем клиент сгенерирует SocketTimeoutException на стороне базы данных, я проверил таблицу pg_stat_activity. Соответствующая строка для запроса выше имела wait_event_type=Client и wait_event=ClientWrite. Кроме того, в журнал сервера базы данных входят сообщения о том, что соединение потеряно.

LOG:  unexpected EOF on client connection with an open transaction
LOG:  could not send data to client: Connection timed out
FATAL:  connection to client lost

Версия

  • PostGIS-jdbc: 2.2.1 (postgresql jdbc: 9.4.1208.jre7)
  • HikariCP: 3.1.0
  • Сервер Postgres: 10,3
  • Сервер PostGIS: 2.4.4

Если я не установлю socketTimeout через строку соединения jdbc, то соединение застрянет навсегда. Как только соединение достигает максимального срока службы, оно будет разорвано и подключено снова. Тем не менее, он все еще не может прочитать данные. Когда я установлю socketTimeout, тогда будет сгенерировано исключение.

UPDATE Если socketTimeout не установлено, то в таблице pg_stat_activity будет строка для соединения со следующими значениями: state=idle in transaction, wait_event_type=Client и wait_event=ClientRead.

Я предполагаю, что какая-то сетевая настройка блокирует чтение с сервера на стороне клиента. Как я могу далее отладить это и найти основную причину?

1 Ответ

0 голосов
/ 06 июня 2018

Мы обнаружили, что это было вызвано настройкой MTU сервера базы данных. MTU был установлен на 9000 по умолчанию и привел к потере пакета. Изменение на 1500 решило проблему.

...