Нечетное 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.
Мне жаль, что я расплывчата, но надеюсь, что это поможет вам...