Нечетное SQLException - не удалось получить сервер состояния доступности только для чтения

У меня есть Quartz Работа, выполняющая хранимую процедуру в моей базе данных MySQL каждые 5 минут, и по какой-то причине 1 из 3 исполнений терпит неудачу и дает это странное исключение. Я искал и искал то, что означает это исключение, но я не мог найти решение. Вот полная трассировка стека:

java.sql.SQLException: Could not retrieve transation read-only status server
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:951)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:941)
    at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3939)
    at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3910)
    at com.mysql.jdbc.PreparedStatement.checkReadOnlySafeStatement(PreparedStatement.java:1258)
    at com.mysql.jdbc.CallableStatement.checkReadOnlySafeStatement(CallableStatement.java:2656)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1278)
    at com.mysql.jdbc.CallableStatement.execute(CallableStatement.java:920)
    at com.mchange.v2.c3p0.impl.NewProxyCallableStatement.execute(NewProxyCallableStatement.java:3044)
    at org.deadmandungeons.website.tasks.RankUpdateTask.execute(RankUpdateTask.java:30)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 1,198,219 milliseconds ago.  The last packet sent successfully to the server was 950,420 milliseconds ago.
    at sun.reflect.GeneratedConstructorAccessor43.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1121)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3673)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3562)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4113)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2812)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2761)
    at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1612)
    at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3933)
    ... 9 more
Caused by: java.net.SocketException: Connection timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:150)
    at java.net.SocketInputStream.read(SocketInputStream.java:121)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3116)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3573)
    ... 17 more

Итак, я понял, что это время, потому что он думает, что сервер MySQL находится в состоянии только для чтения? Это происходит только для этого задания кварца, а не в другое время, когда я общаюсь с базой данных. Это исполнение, конечно, происходит в другом потоке, но я не думаю, что это имело бы какое-либо отношение к нему. Почему он думал, что сервер находится в режиме только для чтения?

Кроме того, я не думаю, что "трансация" - это слово, поэтому там...

Ответы

Ответ 1

Извините за публикацию в старой теме,

Как показывает трассировка стека

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Это означает, что связь между JDBC и DB нарушена. Согласно вашему наблюдению вы говорите, что 1 из 3 вызовов работы не работает.

У вас есть эти задания, запланированные каждые 5 минут, и по трассе последнее успешное сообщение, отправленное на сервер, составляет ~ 15 минут раньше.

Поэтому я подозреваю, что

  • Вы не возвращаете процедуру (ожидая чего-то)
  • Соединение JDBC было аннулировано брандмауэром/прокси-сервером

Интересно посмотреть, как управляются соединения. Как и в журналах, я вижу, что вы используете c3p0.

Вы можете попробовать установить unreturnedConnectionTimeout и debugUnreturnedConnectionStackTraces. Это даст вам больше информации о утечках соединений или длинных вызовах db.

Ответ 2

Исследование не происходит нигде, как вы сказали, но ошибка показывает, что, похоже, база данных заполняется двумя приложениями одновременно.

У вас есть права администратора на этом сервере MySQL? Если вы это сделаете, попробуйте установить

FLUSH TABLES WITH READ LOCK;
SET GLOBAL READ_ONLY=ON;

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

SET GLOBAL READ_ONLY=0;
UNLOCK TABLES;

Если результат этого теста положительный (одна и та же ошибка была воспроизведена), вы должны попытаться изолировать приложения, которые хранят данные в вашей базе данных, чтобы выяснить, какой из них противоречит Quartz.

Мне жаль, что я расплывчата, но надеюсь, что это поможет вам...