flyway使用注意事项与问题排查
Posted 今夜月色很美
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flyway使用注意事项与问题排查相关的知识,希望对你有一定的参考价值。
一、flyway介绍
1.1、什么是flyway
Flyway 是一款开源的数据库版本管理工具。它可以很方便的在命令行中使用,或者在Java应用程序中引入,用于管理我们的数据库版本。
在项目或产品中,很难一开始就把业务理清楚,把数据库表设计好,因此数据表也会在迭代周期不断迭代。在Java应用程序中使用Flyway,能快速有效地用于迭代数据库表结构,并保证部署到测试环境或生产环境时,数据表都是保持一致的。
1.2、为什么要使用flyway
我们有多个测试、生产环境,却缺乏统一的sql版本管理,导致每个环境重新部署发布时很难判断有哪些脚本要执行,容易出现某个环境未执行脚本导致项目运行问题,flyway可以替我们管理sql脚本文件版本,并记住每个环境有哪些脚本已经执行过,还需要执行哪些脚本。
1.3、脚本名称约定
sql脚本名称约定格式:V + 版本号 + 双下划线(__) + 描述 + 结束符(.sql)
1.4、版本控制原理
主要是通过对比flyway_schema_history
表中 version
与 checksum
,来判断文件是否存在与被修改过,来执行版本控制的。
1.5、flyway工作流程
1、项目启动,应用程序完成数据库连接池的建立后,Flyway自动运行。
2、初次使用时,Flyway会创建一个flyway_schema_history
表,用于记录sql执行记录。
3、Flyway会扫描项目指定路径下(默认是classpath:db/migration
)的所有sql脚本,与flyway_schema_history
表脚本记录进行比对。如果数据库记录执行过的脚本记录,与项目中的sql脚本不一致,Flyway会报错并停止项目执行。
4、如果校验通过,则根据表中的sql记录最大版本号,忽略所有版本号不大于该版本的脚本。再按照版本号从小到大,逐个执行其余脚本。
二、开发注意事项
1、脚本文件命名V + 版本号 + 双下划线(__) + 描述 + 结束符(.sql),注意是双下划线,另外版本号必须按顺序添加,不可以添加比已经执行过的脚本文件更早的版本号。
2、脚本文件如果已经执行过,便不要在进行任何更改(否则无法通过校验,常见错误2),如果需要修改请通过新增一个新的sql脚本文件来达成。
3、注意脚本文件的正确性,一定要保证脚本的正确
如果脚本有错误导致执行失败,这时脚本改正后还不能直接执行,如果直接执行会发生常见错误1,这是因为flyway在版本管理flyway_schema_history表中收录了改正前的脚本,这时需要把改成前的版本清理掉才可以执行改正后的sql脚本,请找到success为0的版本进行删除,删除后可以执行改正后的sql脚本
4、通常不建议手动更改flyway_schema_history表的数据,因为表中的数据是Sql版本管理的依据。
三、运维注意事项
1、从A数据库还原到B数据库要保证还原后B的表结构和A完全一致,表不能多也不能少(还原后B数据库多一张表或少一张表时有发生),每张表的字段必须和A数据库完全一致。
2、除日志表外,从A数据库还原到B数据库要保证还原后B数据库每张表的数据建议与A数据库完全一致。
3、如果是新创建的环境,注意不要漏掉nacos配置(yaml格式文件对缩进有严格要求,请参考yaml语法)
spring:
flyway:
# 是否启用flyway
enabled: true
# 迁移sql脚本文件存放路径,默认classpath:db/migration
# locations: classpath:db/migration
# 当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,新建schema_version表
baseline-on-migrate: true
# 允许存储占位符$
placeholderReplacement: false
四、常见错误与排查方法
4.1、sql查询版本管理记录
如果启动失败,首先查看flyway_schema_history是否有success为0的记录,如果有,查看script字段即执行失败的sql脚本文件名,找到这个文件(运维查看sql脚本路径xxx-system-1.0.0.jar\\BOOT-INF\\classes\\db\\migration ),检查这个sql脚本执行失败的原因,如果运维不能确定失败原因,请把文件名发到开发群里,由sql文件提交者排查执行失败原因。
SELECT * FROM SLSPD."flyway_schema_history" ORDER BY "version" DESC;
字段解释:
installed_rank:执行序号
version:版本
script:sql脚本文件
checksum:类似文件md5值,flyway用来判断文件是否被修改
success:是否执行成功,1成功,0失败
如果手写sql查询版本管理记录提示表或视图不存在,这是因为flyway_schema_history表名是小写的,请在表名上加双引号(oracle表和字段有大小写的区别,oracle默认是大写,如果我们用双引号括起来的就区分大小写,如果没有,系统会自动转成大写)。
4.2、查看system日志
以xx服务器为例
进入日志目录:
cd /xxx/logs
查看最后400行日志:
tail -400f xxx-system.log
如果system启动失败,日志中有FlywayException异常信息,查询flyway_schema_history表是否有success为0的记录,如果有,按照4.1进行判断,如果没有,请将异常信息发到开发群中,可能是开发修改了已经执行成功的sql脚本文件。
4.3、常见错误1:
sql脚本有错误,执行失败修改后重新执行报错:
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Validate failed:
Detected failed migration to version 20220207.3 (test delete)
需要手动修复,找到对应的约束进行删除:
DELETE FROM SPDCLOUD."flyway_schema_history" WHERE "installed_rank"=xxx;
4.4、常见错误2:
已经执行过的脚本被改动,导致校验失败
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Validate failed:
Migration checksum mismatch for migration version 20220207.1
-> Applied to database : -335589342
-> Resolved locally : -725714856
还原该脚本可以解决
五、某些特殊需求的特殊处理
5.1、修改执行过的脚本
如果因为某些特定原因必须修改已经执行过的脚本,不修改不行,记住修改后脚本的checksum
,手动覆盖到每一个环境的flyway_schema_history版本记录中。
5.2、删除执行过的脚本
由于特殊原因必须删除已经执行过的脚本,例如sql脚本文件过多,想要清理,建议在所有环境同步更新后,再删除sql脚本文件,并对应删除flyway_schema_history里的版本记录。
以上是关于flyway使用注意事项与问题排查的主要内容,如果未能解决你的问题,请参考以下文章