了解 "APPARENT DEADLOCK!!! Complete Status" 详细信息
Understanding "APPARENT DEADLOCK!!! Complete Status" details
我已经在下面发布了一小部分日志,如果有人可以从中解码以下内容,我将不胜感激:
- 列表项
- 托管线程
- 活动线程
- 活动任务
- 待处理任务
- 池线程堆栈跟踪
我有以下 C3PO 配置:
c3p0.minPoolSize=10
c3p0.maxPoolSize=40
c3p0.acquireIncrement=5
c3p0.maxIdleTime=1800
c3p0.maxStatements=50
c3p0.idleConnectionTestPeriod=180
这是日志:
09-02@12:28:43 WARN ThreadPoolAsynchronousRunner [Timer-0] - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@700ec336 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
09-02@12:28:43 WARN ThreadPoolAsynchronousRunner [Timer-0] - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@700ec336 -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 3
Active Threads: 3
Active Tasks:
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@34ac7f2c (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@28d13cb8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@40e968f7 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
Pending Tasks:
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@1bea516c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@348797c5
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@31fd2174
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@619f604f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@266c149b
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@1bcdfd2
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@170a54e2
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@274acd3f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@1fe8f740
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@77c09b1d
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@607ca57
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@697518d8
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@6b242ff
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@214c76c8
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@230a558c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@7b766c4c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@1bc030e7
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@66ca9bec
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@7fc2d7ac
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@50dd9ebb
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@5e03077
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@418dd7a4
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@4748719b
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@651a9bac
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@35e26d0f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@24660f6c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@287e8e1f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@ca4a9fe
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@e94692e
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@3185527c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@27ea644a
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@d5e4abf
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@297d4874
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@601fccf3
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@47c896d2
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@4225d9cf
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@42fec6f6
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@64b862d6
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@5610343
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@241d2677
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@75c86126
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@36624233
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@6ce83e29
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@3492d9b
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@39511ccc
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@7c39b279
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@2ff465a6
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@563d8de2
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@632e1ca9
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@685bce1d
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@63390771
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@3517be9b
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:575)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask.run(GooGooStatementCache.java:404)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:575)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask.run(GooGooStatementCache.java:404)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:575)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask.run(GooGooStatementCache.java:404)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
如果能提供一些关于明显死锁的信息,我们将不胜感激。
线程池包含3个线程。 ("Managed Threads")。他们 3 个人都 "active",正在尝试完成一项任务。 ("Active Threads"),没有准备好工作的休眠线程。列出了任务。它们都是缓存语句关闭任务。
当线程池中的所有任务长时间保持不变时,会触发APPARENT DEADLOCK
。 c3p0(实际上是它下面的线程池库)最终假定,如果池中没有任务成功完成,则池处于死锁状态。库中断()然后丢弃那些线程,并用新的线程替换它们,以便其他任务(你有很长的任务积压,"Pending Tasks")可以尝试运行。
在你的案例中,这个问题是众所周知的。某些 JDBC 驱动程序的 Statement.close()
操作可能会在其父 Connection
正在使用时死锁。对于这些(正式超出规格的)驱动程序,c3p0 实施谨慎的 Statement
关闭策略,其中 Statement
销毁是 tasked asynchronously and only performed when the parent Connection
is known not to be in use.
TL; DR:将 statementCacheNumDeferredCloseThreads
设置为 1。
c3p0.statementCacheNumDeferredCloseThreads=1
我已将连接器更改为
<dependency>
mysql
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
然后就可以了
我已经在下面发布了一小部分日志,如果有人可以从中解码以下内容,我将不胜感激:
- 列表项
- 托管线程
- 活动线程
- 活动任务
- 待处理任务
- 池线程堆栈跟踪
我有以下 C3PO 配置:
c3p0.minPoolSize=10
c3p0.maxPoolSize=40
c3p0.acquireIncrement=5
c3p0.maxIdleTime=1800
c3p0.maxStatements=50
c3p0.idleConnectionTestPeriod=180
这是日志:
09-02@12:28:43 WARN ThreadPoolAsynchronousRunner [Timer-0] - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@700ec336 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
09-02@12:28:43 WARN ThreadPoolAsynchronousRunner [Timer-0] - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@700ec336 -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 3
Active Threads: 3
Active Tasks:
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@34ac7f2c (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@28d13cb8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@40e968f7 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
Pending Tasks:
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@1bea516c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@348797c5
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@31fd2174
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@619f604f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@266c149b
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@1bcdfd2
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@170a54e2
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@274acd3f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@1fe8f740
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@77c09b1d
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@607ca57
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@697518d8
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@6b242ff
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@214c76c8
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@230a558c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@7b766c4c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@1bc030e7
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@66ca9bec
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@7fc2d7ac
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@50dd9ebb
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@5e03077
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@418dd7a4
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@4748719b
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@651a9bac
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@35e26d0f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@24660f6c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask@287e8e1f
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@ca4a9fe
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@e94692e
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@3185527c
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@27ea644a
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@d5e4abf
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@297d4874
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@601fccf3
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@47c896d2
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@4225d9cf
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@42fec6f6
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@64b862d6
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@5610343
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@241d2677
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@75c86126
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@36624233
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@6ce83e29
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@3492d9b
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@39511ccc
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@7c39b279
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStmtAcquireTask@2ff465a6
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@563d8de2
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@632e1ca9
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@685bce1d
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@63390771
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@3517be9b
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:575)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask.run(GooGooStatementCache.java:404)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:575)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask.run(GooGooStatementCache.java:404)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:575)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
com.mchange.v2.c3p0.stmt.GooGooStatementCacheStatementCloseTask.run(GooGooStatementCache.java:404)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
如果能提供一些关于明显死锁的信息,我们将不胜感激。
线程池包含3个线程。 ("Managed Threads")。他们 3 个人都 "active",正在尝试完成一项任务。 ("Active Threads"),没有准备好工作的休眠线程。列出了任务。它们都是缓存语句关闭任务。
当线程池中的所有任务长时间保持不变时,会触发APPARENT DEADLOCK
。 c3p0(实际上是它下面的线程池库)最终假定,如果池中没有任务成功完成,则池处于死锁状态。库中断()然后丢弃那些线程,并用新的线程替换它们,以便其他任务(你有很长的任务积压,"Pending Tasks")可以尝试运行。
在你的案例中,这个问题是众所周知的。某些 JDBC 驱动程序的 Statement.close()
操作可能会在其父 Connection
正在使用时死锁。对于这些(正式超出规格的)驱动程序,c3p0 实施谨慎的 Statement
关闭策略,其中 Statement
销毁是 tasked asynchronously and only performed when the parent Connection
is known not to be in use.
TL; DR:将 statementCacheNumDeferredCloseThreads
设置为 1。
c3p0.statementCacheNumDeferredCloseThreads=1
我已将连接器更改为
<dependency>
mysql
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
然后就可以了