百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

互联网微服务:使用Flyway版本化管理数据库脚本

mhr18 2025-07-09 15:11 4 浏览 0 评论

本文将着重介绍当前互联网公司基于Springboot开发的微服务使用Flyway管理脚本。

1. 目的

为解决研发流程中项目脚本管理,实现CI/CD自动化部署升级脚本,特引入数据库版本管理工具Flyway,使我们的数据库能够做到增量升级。

2. Flyway

2.1. 说明

Flyway是一个简单开源数据库版本控制器(约定大于配置),主要提供migrate、clean、info、validate、baseline、repair等命令。它支持SQL(PL/SQL、T-SQL)方式和Java方式,支持命令行客户端等,还提供一系列的插件支持(Maven、Gradle、SBT、ANT等)。

2.2. 版本

采用最新版本:5.2.4。

2.3. 特性

l 普通SQL:纯SQL脚本(包括占位符替换)没有专有的XML格式,没有锁定;

l 无限制:使用Java 代码来进行一些高级数据操作;

l 零依赖:只需运行在Java6(及以上)和数据库所需的JDBC驱动;

l 约定优于配置:迁移时,自动查找系统文件和类路径中的SQL文件或Java类;

l 高可靠性:在集群环境下进行数据库升级是安全可靠的;

l 云支持:完全支持 Microsoft SQL Azure, Google Cloud SQL& App Engine、Heroku Postgres 和 Amazon RDS;

l 自动迁移:使用Fly提供的API,让应用启动和迁移同时工作;

l 快速失败:损坏的数据库或失败的迁移可以防止应用程序启动;

l 数据库清理:在一个数据库中删除所有的表、视图、触发器,而不是删除数据库本身。

2.4. 支持的数据库

数据库

版本

说明

Oracle

10g及以上


SQL Server

2008及以上


MySQL

5.1及以上


PostgreSQL

9.0及以上


SQLite

3.7.2及以上


还有其余的10几种数据库,这里不再详述。

2.5. 工作原理

最简单的场景是当你用Flyway迁移到一个空数据库时。



Flyway将会试图查找数据库中的元数据表(metadata table)。由于数据库是空的,Flyway 将不会查找,而是创建一个新元数据表。

现在数据库中将有一张名为SCHEMA_VERSION的表:

此表将用于跟踪数据库的状态。

之后,使用Flyway进行迁移时将扫描系统文件或者应用的类路径中特定的文件,它们可以由SQL或Java编写。

然后Flyway将基于他们的版本号进行排序并依次执行:

随着每次执行,对应地更新元数据表schema_version:

元数据表的创建和初始化,我们现在可以讨论迁移到一个新的版本。

Flyway进行迁移时会重新扫描系统文件或者应用的类路径中特定的文件,并且与元数据表进行校验,如果它们的版本号低于或等于当前标记的版本,它们将被忽略。

而高于标记的文件将等待迁移:状态为可用(available),但是未执行。、

Flyway会将它们按照版本号进行排序并依次执行。

元数据表相应的更新:

3. 使用方式

3.1. Springboot集成

3.1.1. 配置

Maven依赖和插件

<dependency>

<groupId>org.flywaydb</groupId>

<artifactId>flyway-core</artifactId>

<version>5.2.4</version>

</dependency>

 <plugin>

      <groupId>org.flywaydb</groupId>

      <artifactId>flyway-maven-plugin</artifactId>

      <version>5.2.4</version>

   </plugin>

application.yml配置

最新版本的springboot是把flyway集成进去了。Flyway的配置可以在spring中找到;低版本的,可直接以flyway开头设置配置参数。大家视各自项目情况而定。

spring:

  datasource:

    driver-class-name: org.postgresql.Driver

    url: jdbc:postgresql://localhost:5432/sgs_test

    username: postgres

    password: pass@123



  flyway:

    ## 是否启用flyway,提交到develop和master分支时,需要设置为false

    enabled: true

    ## 编码格式,默认UTF-8

    encoding: UTF-8

    ## 迁移sql脚本文件存放路径,默认db/migration

    locations: classpath:db/migration

    ## 迁移sql脚本文件名称的前缀,默认V

    sql-migration-prefix: V

    ## 迁移sql脚本文件名称的分隔符,默认2个下划线__

    sql-migration-separator: __

    ## 迁移sql脚本文件名称的后缀

    sql-migration-suffixes: .sql

    ## 迁移时是否进行校验,默认true

    validate-on-migrate: true

    #设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema

    schemas: public

    #元数据表,记录脚本升级信息

    table: schema_version

    #设置为true,当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,SCHEMA_VERSION(默认表名,

    #自定义表名可参考参数table的值)

    baseline-on-migrate: true

    #是否允许无序的迁移,默认false,对于开发环境, 可能是多人协作开发,

    #很可能先apply了自己本地的最新SQL代码,然后发现其他同事早先时候提交的SQL代码还没有apply,

    #所以开发环境应该设置true,这样flyway将能加载漏掉的老版本SQL文件,生产环境可以设置为false

    out-of-order: true

    #执行基线时用来标记已有Schema的版本,默认值为1

    baseline-version: 1.0.0

    baseline-description: "初始化"


3.1.2. 脚本

存放位置可根据实际情况设置,一般默认在Springboot项目的resources目录下创建,匹配application.yml中参数locations,脚本命名规范也如下图所示(详细见章节3.1.2)。

3.1.3. 案例说明

相关配置见章节3.1。这里我演示下本地的迁移示例:

上图中,项目组可以根据实际情况对脚本归类。虽然创建了一个文件夹,对某一类脚本进行归类,但flyway仍然会全目录(db/migration)扫描,按照文件名顺序执行。

3.1.4. 规范

脚本命名:在增加前缀V的前提下,后面紧跟版本号,格式如:1.0.0(版本迭代时书写新的版本号,不能小于基线版本),其后再紧跟脚本书写的时间,格式为.yyyyMMddHHmmss。如下图:

编辑规范:如果要给某个表作修改或做其它操作,原脚本已使用Flyway已迁移后;那么,就不要在原来的脚本内容上做修改,请提交新的脚本进行你要的操作;也不要修改脚本文件名中的版本,这样操作的话无法做到脚本的版本管理,同时该脚本也会执行出错。

3.1.5. 注意事项

与Springboot集成这种方式,需要每个环境在打包之前,将application.yml文件中的参数替换成对应的环境值,如:数据库链接、数据库用户名、密码等。

3.2. 命令行

需要下载flyway-commandline命令行工具,按照环境下载不同的安装包。

下载地址:
https://flywaydb.org/documentation/commandline/#download-and-installation。


3.2.1. 配置

编辑/conf/flyway.conf文件:

3.2.2. 执行命令

第一次执行flyway migrate可能会报以下错误。

数据要先指定基线版本,先执行flyway baseline,这时候在对应的数据库里头创建一张版本更新表:schema_version,然后再执行flyway migrate,特别注意执行flyway baseline后脚本最低版本要从2开始。另外注意:由于flyway创建schema_version表时候,多了””,所以查询数据库要加””,例如:select t.* from "schema_version" t;

flyway info输出操作记录信息。

4. CI工具jenkins集成

4.1. 使用maven单独创建项目

使用maven单独创建一个项目来管理脚本(相关配置,参考章节3.1),然后在jenkins pipeline中加入对应环境的脚本执行任务。

4.2. 集成到现有微服务项目中

4.2.1. 使用一个配置文件

需要运维人员在每次从不同环境打包之前,将application.yml文件中的数据库相关配置及flyway要升级的目标数据库的基线版本信息。目前,演示环境和生产环境的打包时,是只打一次包,然后才决定往那个环境部署;而flyway集成到项目中后,它会在编译打包时就会执行脚本到目标数据库中。因此,需要运维人员在jenkins上增加配置命令,将application.yml文件在决定往不同环境编译打包之前替换。

优点:运维在启动微服务时,不需要在启动命令行中设置相关的系统参数变量;

缺点:需要运维针对不同的环境提前准备好相应配置的application.yml。

4.2.2. 使用多个配置文件

Springboot使用profiles可以动态切换不同的配置文件,故开发人员提前在项目中创建5个配置文件,具体如下:

application.yml:此文件主要用来配置动态切换,即设置spring.profiles.active=dev;//开发配置dev,测试test,演示demo,生产prod;

application-dev.yml:开发环境参数配置文件;

application-test.yml:测试环境参数配置文件;

application-demo.yml:演示环境参数配置文件;

application-prod.yml:生产环境参数配置文件。

上面说到,其余的相关参数配置,就可以前往其它4个配置文件,不同环境,只是参数值不一样而已,一次配好,无须在各个环境启动时命令行设置大量的系统参数。

同样,需要运维人员在每次从不同环境打包之前,需要确定部署目标,然后修改application.yml文件中spring.profiles.active值。

优点:运维人员不需要关心不同环境配置文件,只需在启动时,命令设置active参数值即可;

缺点:需要开发需要提前在项目中准备好不同环境的配置文件,并设置好参数值(如需变动,运维根据实际情况而定)。

4.3. 命令行方式

该方式,需要在不同环境下载flyway-commandline命令行工具,且需要将脚本文件单独存放(不在项目中),同时需要在每个环境单独设置数据库链接、用户名和密码等参数,比较繁琐。

4.4. 使用现有的编译打包模式(使用该方式)

该方式与上面几种方式不同,不会更改现有的jenkins流程。

主干的develop和master分支默认设置flyway.enabled=false(开发人员自己的环境可设置为true),运维人员在docker中命令行启动项目时设置命令行参数flyway.enabled=true即可

优点:对当前CI/CD流程不做处理,简化了运维人员的工作;

缺点:需要设置命令行参数(不同版本的springboot,可能参数不一样,大体分为:spring.flyway.enabled和flyawy.enabled)。


5. 升级问题

1) 某微服务的数据库schema下已经存在之前的表结构和数据,该怎么办?

答:我们采用的是flyway的baseline模式,新的脚本版本大于基线即可。因为flyway迁移脚本的原则是根据基线版本号比较db/migration目录下的脚本文件版本号进行升级迁移。

2) 如果当前开发环境的基线是1.2.0,测试环境是1.1.9,而demo环境的又是1.1.8,使用flyway该怎么升级呢?

答:需要手动将测试和demo环境的表结构或数据的版本与开发环境一致后,方可采用flyway升级。

6. 参考资料

官网:https://flywaydb.org/getstarted/how;

命令行:https://flywaydb.org/getstarted/firststeps/commandline;

命令行工具安装包:https://flywaydb.org/documentation/commandline/#download-and-installation;

Jenkins集成:http://blog.chinaunix.net/uid-29335043-id-5751362.html;

相关推荐

mysql一 基本操作(mysql基础操作命令)

先讲数据库--mysql、redis、MongoDB爬虫今天的内容:mysql一基本操作注意事项:1.安装:自己安装,有问题可以问老师、可以自己找办法解决2.上课:先讲知识点再回答问题3....

香港DM德馬景泰藍文科集團20250702期《生命的收獲》LIN JING DE

香港DM德馬景泰藍文科集團20250702期《生命的收獲》DMSIXSEVEN/LINJINGDE/1973主編供圖:香港DM德馬數字甲骨文集團Hongkong-basedDMDelm...

01.Java发展历史(java发展简史)

1.Java发展历史Java由SunMicrosystems公司(现为Oracle公司)的JamesGosling及其团队在1991年开发,最初命名为"Oak",后改名为"...

月薪最高12000!看看这些宝山岗位有没有你心仪的~

招聘目录信息1猎上网络科技(上海)有限公司职位分析师职位分析师助理2上海祥腾金属材料有限公司商务车驾驶员3上海赋拓物联网技术有限公司软件测试工程师4上海集优标五高强度紧固件有限公司...

69岁的Java之父终于退休了,他竟然也经历过职场PUA

有些程序员不到35岁就要担心被优化,但有的程序员干到了69岁的高龄,才准备退休。就前几天,Java之父詹姆斯·高斯林,自个儿在领英上宣布以后要美美享受退休生活了。这一下子,就炸出了不少...

ocm认证年薪多少?(ocm认证好考吗)

从业数据库方面的工程师待遇都很好,年薪30万都是比较平常的事。OCM认证的价值可以归纳成以下几点:1、可以全面掌握Oracle知识,专业知识完善;2、证书对于公司招投标有巨大作用,甚至可以不上班就拿钱...

自学java开发攻略,想做程序员的必备攻略?

背景现阶段,随着互联网的快速发展,程序员这个行业越来月吃香,不仅仅是因为科技先进,说出去很牛逼,让别人产生崇拜,主要原因是程序员行业薪资待遇好,相比国内其他行业,程序员的薪资待遇是羡慕了很多人呢!于是...

SpringBoot WebFlux整合R2DBC实现数据库反应式编程

环境:Springboot2.4.12R2DBC简介SpringdataR2DBC是更大的Springdata系列的一部分,它使得实现基于R2DBC的存储库变得容易。R2DBC代表反应式关系数...

AI编码工具未能代替码农:大模型的局限性揭秘

随着ChatGPT和GithubCopilot等AI编码工具的兴起,StackOverflow近日因流量减少宣布裁员近三分之一。这引发了一个争议的问题:ChatGPT这类AI编码工具,真的要颠覆整...

大模型无法替代码农!GPT-4解决GitHub编程问题成功率为0

编辑:编辑部【新智元导读】ChatGPT之类的AI编码工具来势汹汹,StackOverflow又裁员了!不过,普林斯顿和芝大竟发现,面对真实世界GitHub问题,GPT-4的解决率竟是0%。Stac...

机器人动作领域突破!UniVLA模型实现跨模态AI机器人动作统一

还记得《星际穿越》中那台能在无重力、尘暴甚至巨浪中切换形态、随时理解库珀指令的TARS多功能机器人吗?在银幕里,我们羡慕TARS能听懂人话、看懂环境、马上给出最合适的动作;而在现实世界的实验室里,“让...

FEA-Bench:首个仓库级新功能实现基准,让大模型更懂软件开发

当前,大语言模型在代码生成领域已展现出惊人的能力,但能否胜任真实软件开发中的“新增功能实现”任务,仍是一个关键未解的问题。对此,微软亚洲研究院与北京大学联合发布了首个专注于仓库级新功能实现的基准测试...

基于Java的软件版本信息管理系统-2025计算机毕业设计

基于Java的软件版本信息管理系统-2025计算机毕业设计前言随着移动互联网的快速发展,APP已成为人们日常生活中不可或缺的一部分。为了高效地管理这些APP的信息,如版本更新、用户反馈、下载量统计等,...

马斯克在干嘛?抱着它现身推特 简介改为“推特老板”

  马斯克收购推特的交易真是“没完没了”。据彭博社报道,当地时间26日,美国亿万富翁埃隆·马斯克抱着水槽走进了推特公司的旧金山总部,他还将自己在推特账号的公开自我介绍改为“推特老板”(ChiefTw...

福布斯公布7月全球十大富豪:马斯克成6月最大“输家”,身家缩水160亿美元

7月日,福布斯今日公布了2025年7月全球十大富豪榜,其中第二名迎来新面孔。软件巨头甲骨文(Oracle)联合创始人兼董事长拉里埃里森(LarryEllison)凭借公司股价飙升成功上位。由...

取消回复欢迎 发表评论: