【发布时间】:2020-10-19 16:22:12
【问题描述】:
我们的应用程序包含不能简单回滚的测试。所以我们决定使用flyway的java API。我们将此方法添加到测试中:
@AfterEach
public void remigrate() {
flyway.clean();
flyway.migrate();
}
在日志中我发现只有这个:
2020-06-29 15:20:10.356 DEBUG [-] 1044 --- [ main] o.f.c.i.s.classpath.ClassPathScanner : Found resource: db/migration/V0_0_1__database-initialization.sql
2020-06-29 15:20:10.356 DEBUG [-] 1044 --- [ main] o.f.c.i.s.classpath.ClassPathScanner : Scanning for classes at classpath:db/migration
2020-06-29 15:20:10.356 DEBUG [-] 1044 --- [ main] o.f.c.i.c.SqlScriptCallbackFactory : Scanning for SQL callbacks ...
2020-06-29 15:20:10.356 DEBUG [-] 1044 --- [ main] o.f.core.internal.util.FeatureDetector : Spring Jdbc available: true
2020-06-29 15:20:10.361 DEBUG [-] 1044 --- [ main] o.f.core.internal.command.DbClean : Cleaning schema "public" ...
此应用程序卡住后。当我尝试选择飞行路线历史表记录时,数据库客户端仅加载。其他表上的选择工作正常,所以我预计 flyway 会在历史表上创建死锁。你知道如何解决它吗?谢谢。
执行器 threaddump 中与 flyway 的 clean 相关的最后一个堆栈跟踪:
{
methodName: "socketRead0",
fileName: "SocketInputStream.java",
lineNumber: -2,
className: "java.net.SocketInputStream",
nativeMethod: true
},
{
methodName: "socketRead",
fileName: "SocketInputStream.java",
lineNumber: 116,
className: "java.net.SocketInputStream",
nativeMethod: false
},
{
methodName: "read",
fileName: "SocketInputStream.java",
lineNumber: 171,
className: "java.net.SocketInputStream",
nativeMethod: false
},
{
methodName: "read",
fileName: "SocketInputStream.java",
lineNumber: 141,
className: "java.net.SocketInputStream",
nativeMethod: false
},
{
methodName: "readMore",
fileName: "VisibleBufferedInputStream.java",
lineNumber: 140,
className: "org.postgresql.core.VisibleBufferedInputStream",
nativeMethod: false
},
{
methodName: "ensureBytes",
fileName: "VisibleBufferedInputStream.java",
lineNumber: 109,
className: "org.postgresql.core.VisibleBufferedInputStream",
nativeMethod: false
},
{
methodName: "read",
fileName: "VisibleBufferedInputStream.java",
lineNumber: 67,
className: "org.postgresql.core.VisibleBufferedInputStream",
nativeMethod: false
},
{
methodName: "receiveChar",
fileName: "PGStream.java",
lineNumber: 321,
className: "org.postgresql.core.PGStream",
nativeMethod: false
},
{
methodName: "processResults",
fileName: "QueryExecutorImpl.java",
lineNumber: 1978,
className: "org.postgresql.core.v3.QueryExecutorImpl",
nativeMethod: false
},
{
methodName: "execute",
fileName: "QueryExecutorImpl.java",
lineNumber: 309,
className: "org.postgresql.core.v3.QueryExecutorImpl",
nativeMethod: false
},
{
methodName: "executeInternal",
fileName: "PgStatement.java",
lineNumber: 446,
className: "org.postgresql.jdbc.PgStatement",
nativeMethod: false
},
{
methodName: "execute",
fileName: "PgStatement.java",
lineNumber: 370,
className: "org.postgresql.jdbc.PgStatement",
nativeMethod: false
},
{
methodName: "executeWithFlags",
fileName: "PgPreparedStatement.java",
lineNumber: 149,
className: "org.postgresql.jdbc.PgPreparedStatement",
nativeMethod: false
},
{
methodName: "execute",
fileName: "PgPreparedStatement.java",
lineNumber: 138,
className: "org.postgresql.jdbc.PgPreparedStatement",
nativeMethod: false
},
{
methodName: "execute",
fileName: "ProxyPreparedStatement.java",
lineNumber: 44,
className: "com.zaxxer.hikari.pool.ProxyPreparedStatement",
nativeMethod: false
},
{
methodName: "execute",
fileName: "HikariProxyPreparedStatement.java",
lineNumber: -1,
className: "com.zaxxer.hikari.pool.HikariProxyPreparedStatement",
nativeMethod: false
},
{
methodName: "invoke",
fileName: null,
lineNumber: -1,
className: "sun.reflect.GeneratedMethodAccessor103",
nativeMethod: false
},
{
methodName: "invoke",
fileName: "DelegatingMethodAccessorImpl.java",
lineNumber: 43,
className: "sun.reflect.DelegatingMethodAccessorImpl",
nativeMethod: false
},
{
methodName: "invoke",
fileName: "Method.java",
lineNumber: 498,
className: "java.lang.reflect.Method",
nativeMethod: false
},
{
methodName: "doExecute",
fileName: "JdbcWrapper.java",
lineNumber: 412,
className: "net.bull.javamelody.JdbcWrapper",
nativeMethod: false
},
{
methodName: "invoke",
fileName: "JdbcWrapper.java",
lineNumber: 137,
className: "net.bull.javamelody.JdbcWrapper$StatementInvocationHandler",
nativeMethod: false
},
{
methodName: "invoke",
fileName: "JdbcWrapper.java",
lineNumber: 294,
className: "net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler",
nativeMethod: false
},
{
methodName: "execute",
fileName: null,
lineNumber: -1,
className: "com.sun.proxy.$Proxy207",
nativeMethod: false
},
{
methodName: "execute",
fileName: "JdbcTemplate.java",
lineNumber: 215,
className: "org.flywaydb.core.internal.jdbc.JdbcTemplate",
nativeMethod: false
},
{
methodName: "doDrop",
fileName: "PostgreSQLTable.java",
lineNumber: 43,
className: "org.flywaydb.core.internal.database.postgresql.PostgreSQLTable",
nativeMethod: false
},
{
methodName: "drop",
fileName: "SchemaObject.java",
lineNumber: 81,
className: "org.flywaydb.core.internal.database.base.SchemaObject",
nativeMethod: false
},
{
methodName: "doClean",
fileName: "PostgreSQLSchema.java",
lineNumber: 97,
className: "org.flywaydb.core.internal.database.postgresql.PostgreSQLSchema",
nativeMethod: false
},
{
methodName: "clean",
fileName: "Schema.java",
lineNumber: 149,
className: "org.flywaydb.core.internal.database.base.Schema",
nativeMethod: false
},
{
methodName: "call",
fileName: "DbClean.java",
lineNumber: 172,
className: "org.flywaydb.core.internal.command.DbClean$3",
nativeMethod: false
},
{
methodName: "call",
fileName: "DbClean.java",
lineNumber: 169,
className: "org.flywaydb.core.internal.command.DbClean$3",
nativeMethod: false
},
{
methodName: "execute",
fileName: "TransactionTemplate.java",
lineNumber: 74,
className: "org.flywaydb.core.internal.jdbc.TransactionTemplate",
nativeMethod: false
},
{
methodName: "cleanSchema",
fileName: "DbClean.java",
lineNumber: 169,
className: "org.flywaydb.core.internal.command.DbClean",
nativeMethod: false
},
{
methodName: "clean",
fileName: "DbClean.java",
lineNumber: 113,
className: "org.flywaydb.core.internal.command.DbClean",
nativeMethod: false
},
{
methodName: "doClean",
fileName: "Flyway.java",
lineNumber: 1488,
className: "org.flywaydb.core.Flyway",
nativeMethod: false
},
{
methodName: "access$300",
fileName: "Flyway.java",
lineNumber: 85,
className: "org.flywaydb.core.Flyway",
nativeMethod: false
},
{
methodName: "execute",
fileName: "Flyway.java",
lineNumber: 1506,
className: "org.flywaydb.core.Flyway$3",
nativeMethod: false
},
{
methodName: "execute",
fileName: "Flyway.java",
lineNumber: 1499,
className: "org.flywaydb.core.Flyway$3",
nativeMethod: false
},
{
methodName: "execute",
fileName: "Flyway.java",
lineNumber: 1711,
className: "org.flywaydb.core.Flyway",
nativeMethod: false
},
{
methodName: "clean",
fileName: "Flyway.java",
lineNumber: 1499,
className: "org.flywaydb.core.Flyway",
nativeMethod: false
},
【问题讨论】:
-
您是否尝试过执行线程转储并查看卡在哪里?
-
@MarkBramnik 不,你能告诉我该怎么做吗?
-
方法有很多。您可以插入 JVisualVM 甚至远程调试器之类的工具并进行线程转储(在 intelliJ 中,它是调试器窗口中照片相机的标志)。如果你无权使用这些工具,你可以使用 spring boot actuator 来生成线程转储(
/threaddump端点) -
@MarkBramnik 我尝试找出线程转储,我发现一些执行flyway clean的线程堆栈跟踪。我将其添加到问题中。
-
"清理架构“公共”..." 这是正确的架构吗? Postgres 文档表明这可能不是正确的模式?见“
5.8.2. The Public Schema”:postgresql.org/docs/11/ddl-schemas.html#DDL-SCHEMAS-PUBLIC。检查您的数据库中clean()之后的public架构的内容,以确认其未被擦除
标签: spring postgresql spring-boot flyway