Устранение неполадок: «SQLException: превышено время ожидания блокировки» - PullRequest
7 голосов
/ 19 мая 2009

У меня есть приложение под управлением Quartz 1.6.1 с постоянным хранилищем заданий, с MySQL 5.1 в качестве базы данных. Это приложение раньше нормально загружалось в Tomcat6. В какой-то момент он начал выдавать следующее исключение при КАЖДОЙ загрузке:

- MisfireHandler: Error handling misfires: Failure obtaining db row lock: Lock wait timeout exceeded; try restarting transaction
org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: Lock wait timeout exceeded; try restarting transaction [See nested exception: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction]
    at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:112)
    at org.quartz.impl.jdbcjobstore.DBSemaphore.obtainLock(DBSemaphore.java:112)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.doRecoverMisfires(JobStoreSupport.java:3075)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.manage(JobStoreSupport.java:3838)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.run(JobStoreSupport.java:3858)
Caused by: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1885)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:92)
    ... 4 more

Я должен упомянуть, что это приложение также использует JPA с Hibernate, используя C3P0 для пула соединений с источниками данных. Это исключение всегда генерируется сразу после того, как JPA завершает обновление моей схемы.

Сначала я обновился до Quartz 1.6.5, и исключение исчезло, но приложение кажется замороженным. Последняя вещь в журналах - где раньше было исключение - это:

...hbm2ddl stuff...
2969 [Thread-1] INFO org.hibernate.tool.hbm2ddl.SchemaUpdate - schema update complete
- Handling 6 trigger(s) that missed their scheduled fire-time.

После чего ничего не происходит, и веб-приложение не обслуживает запросы; они просто зависают до бесконечности.

Когда я запускаю mysql клиент командной строки с SHOW INNODB STATUS сразу после исключения, он последовательно отображает две подозрительные транзакции:

----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 49, signal count 49
Mutex spin waits 0, rounds 2100, OS waits 0
RW-shared spins 115, OS waits 49; RW-excl spins 0, OS waits 0
------------
TRANSACTIONS
------------
Trx id counter 0 165688
Purge done for trx's n:o < 0 165685 undo n:o < 0 0
History list length 12
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, OS thread id 5012
MySQL thread id 8, query id 1798 localhost 127.0.0.1 root
SHOW INNODB STATUS
---TRANSACTION 0 165687, ACTIVE 300 sec, OS thread id 3772
2 lock struct(s), heap size 320, 1 row lock(s)
MySQL thread id 30, query id 1795 localhost 127.0.0.1 my_app
---TRANSACTION 0 165685, ACTIVE 360 sec, OS thread id 5460
2 lock struct(s), heap size 320, 1 row lock(s), undo log entries 1
MySQL thread id 34, query id 1680 localhost 127.0.0.1 my_app

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

Обновление: Я удалил все строки в таблице qrtz_simple_triggers без проблем. Затем я попытался сделать то же самое для таблицы qrtz_triggers , и мой клиент MySQL выдал ошибку «Время ожидания блокировки превышено». В этот момент я остановил свое (все еще зависшее) приложение и смог удалить все строки таблицы qrtz_triggers . Как только это было сделано, я смог успешно загрузить свое приложение.

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

1 Ответ

1 голос
/ 30 марта 2012

Вы пробовали запустить
show processlist
или
show full processlist
из командной строки mysql? Обычно они показывают полный sql для запроса, который блокируется. Он также покажет вам, как долго процесс выполняет этот запрос. Это может помочь вам приблизиться к ответу.

...