升级flyway-sbt至9.22.0后sbt flywayMigrate命令挂起问题排查
Flyway-sbt升级至9.22.0后
flywayMigrate挂起问题解决方案 问题核心原因
Flyway 8.x及后续版本对PostgreSQL的事务管控逻辑做了强化,而你的迁移脚本中包含**并发创建索引(CREATE INDEX CONCURRENTLY)**操作——该操作本身不支持在事务内执行,升级后的Flyway默认的事务包裹机制会和这个操作产生冲突,进而导致任务挂起。另外,当前flyway-play版本(7.14.0)与flyway-sbt9.22.0版本兼容性不足,也会加剧这类问题。
具体解决措施
1. 拆分并发索引迁移脚本
将带CONCURRENTLY的索引创建语句单独放在一个迁移文件中,并强制关闭事务包裹:
SET autocommit = ON; CREATE INDEX CONCURRENTLY idx_target_table_column ON target_table(target_column);
Flyway默认会给每个迁移脚本套事务,但CONCURRENTLY操作不允许在事务中执行,手动开启自动提交可以规避这个冲突。
2. 调整Flyway配置参数
在application.conf中补充以下配置,替代单一的flyway.postgresql.transactional.lock = false:
# 全局禁用迁移脚本的事务包裹 flyway.transactional = false # 区分DML和DDL的事务处理,适配PostgreSQL特性 flyway.postgresql.transactional.dml = true flyway.postgresql.transactional.ddl = false
3. 对齐flyway-play版本
当前flyway-play7.14.0和flyway-sbt9.22.0版本跨度太大,存在依赖兼容问题。建议升级flyway-play到适配Flyway 9.x的版本(需确认与Play 2.8.8兼容,推荐9.2.0版本):
修改build.sbt中的依赖:
"org.flywaydb" %% "flyway-play" % "9.2.0"
4. 开启日志排查连接状态
如果以上操作仍未解决,开启Flyway的DEBUG日志,查看连接占用和执行流程:
在logback.xml中添加日志配置:
<logger name="org.flywaydb" level="DEBUG"/>
通过日志可以确认是否存在连接耗尽、锁等待等具体挂起原因。
验证流程
- 先单独执行拆分后的并发索引迁移脚本,确认能正常完成
- 再执行完整的
sbt flywayMigrate,观察任务是否正常结束 - 检查数据库的
flyway_schema_history表,确认所有迁移记录状态为成功
内容的提问来源于stack exchange,提问作者Orion
相关产品推荐
相关产品推荐

