• Spring学习笔记(三十七)——Flyway 数据库版本控制


    1、使用背景

    Flyway,是一个数据库版本管理工具。每次上线新功能的时候,都需要先更新数据库,然后再部署代码。当数据库的更新部分很多时,难免会忘掉,造成升级失败。
    另外一个问题的是,当你的服务是允许客户自己私有部署的时候,每个客户可能都在不同的数据库版本上,这时候对于不同的客户给与不同的升级机制就相当重要了。

    2、Flyway简介


    flyway 的官网:Homepage - Flyway

    flyway会对每次执行过sql脚本保存到flyway_schema_history中,在数据库中将保存sql脚本的版本号和对sql生成checksum,当下次执行数据库迁移的时候就会按照版本号从低往高执行。如果以前的版本号脚本已经执行过就不会执行,如果以前版本的sql脚本已经被修改在执行的过程中则会报错。对flyway的详细描述与介绍可以查看flyway的官网。

    3、Flyway的工作流程

    • 初次使用时,flyway会创建一个flyway_schema_history表,用于记录sql执行记录

    • 启动flyway后,flyway会自动扫描项目指定路径下的所有sql脚本。与flyway_schema_history表脚本记录进行比对。如果数据库记录执行过的脚本记录,与项目中的sql脚本不一致,flyway会报错并停止项目执行。

    • 如果校验通过,则根据表中的sql记录最大版本号,忽略所有版本号 不大于该版本的脚本。再按照版本号从小到大,逐个执行其余脚本。

    4、添加Flyway依赖和插件

    引入flyway插件

    
    <plugin>
        
        <groupId>org.flywaydbgroupId>
        <artifactId>flyway-maven-pluginartifactId>
        <version>5.2.4version>
        
        <dependencies>
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>5.1.6version>
            dependency>
        dependencies>
        
    
    
        <configuration>
            
            <url>jdbc:mysql://127.0.0.1:3306/dbgirl?characterEncoding=utf8url>
            <user>rootuser>
            <password>123456password>
            
            <locations>
                <location>filesystem:src/main/resources/sql/flyway/migratelocation>
            locations>
            
            <baselineVersion>1.0.0baselineVersion>
        configuration>
    plugin>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    引入插件后可以使用maven来直接调用flyway的命令,

    mvn flyway:baseline //初始化数据库链接
    mvn flyway:migrate  //迁移数据
    
    • 1
    • 2

    idea则可以通过右边工具栏Maven下的Plugins来调用flyway的命令
    在这里插入图片描述

    注意:flyway的插件配置,不是自动读取application.properties的内容,需要另外在configuration里面配置的。

    引入flyway依赖

    
    <dependency>
        <groupId>org.flywaydbgroupId>
        <artifactId>flyway-coreartifactId>
        <version>5.2.4version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    引入flyway依赖后每次项目打包后,会自动将指定目录下的sql脚本进行打包;执行项目文件后,会将打包中的sql脚本进行迁移合并(运行指定目录下的sql脚本)。

    5、脚本目录和脚本命名

    5.1、脚本目录

    迁移脚本的位置,默认db/migration(可以自行在配置中修改)。
    在这里插入图片描述

    5.2、SQL脚本命名规范

    使用migrate必须开头是V+版本号+__+描述.sql
    如 V1.0.0_20220815__dbgirl.sql
    
    • 1
    • 2

    每个迁移脚本的名字都是有规律的,必须是以V字母开头,然后放版本号(小数点有多少个不限制),然后是2个下划线,少一个下划线都不行,最后接上版本描述。必须以sql作为后缀名。

    6、插件介绍

    6.1、clean

    清楚掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作再dev和test阶段很好用,但是在生产环境务必禁用。

    6.2、baseline

    对已经存在数据库schema结构的数据库的一种解决方案。实现在非空数据库新建metaData flyway_schema_history表,并把Migrations应用到该数据库;也可以在已有表格的数据库中添加metaData数据表。注:对已有的数据结构的数据库来说,必须要进行baseline,才能进行migrate。

    6.3、migrate

    migrate的命令是,对数据库连接后,执行迁移。迁移的原理是:

    • 如果当前数据库是空的,且没有flyway_schema_history,那么就会创建flyway_schema_history,它里面会保存每个脚本的执行情况,以及当前的数据库版本号。
    • 如果当前数据库不是空的,且有flyway_schema_history。那么就会查询flyway_schema_history的版本号,假设这个版本号为1.0.0.1。那么它就会执行1.0.0.1之后的迁移脚本,并在flyway_schema_history中记录这个迁移的情况。

    6.4、validate

    validation的原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。

    validation的功能在每次migration的时候都会执行,它是用来防止这种情况。开发者对某个A版本号的sql脚本迁移到了数据库,然后又修改了这个A版本号的脚本,这样就会产生不同机器下的迁移结果不一致的情况。validation就是用来检查每个迁移脚本的hash值是否与数据表flyway_schema_history的hash值是否一致,来确定开发者有没有偷偷改脚本的这个问题。

    注意,我们永远不要对已经发布的迁移脚本进行修改,这是不行的。

    6.5、info

    查看当前已迁移脚本信息(flyway_schema_history表)
    在这里插入图片描述

    6.6、undo

    这个命令不要用,在社区版的flyway是残废和bug的,回滚数据自己靠自己。

    7、SpringBoot配置

    7.1、常用配置

    # baseline的描述
    spring.flyway.baseline-description = 我是基线描述
    
    # 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
    spring.flyway.baseline-on-migrate = true
    
    # baseline的版本号,默认为1.0
    spring.flyway.baseline-version = 0.9
    
    # validation的原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。
    # 当发现校验错误时是否自动调用clean,默认false.
    spring.flyway.clean-on-validation-error = false
    
    # 是否开启flywary,默认true.
    spring.flyway.enabled = true
    
    # 设置迁移时的编码,默认UTF-8.
    spring.flyway.encoding = UTF-8
    
    # 当读取元数据表时是否忽略错误的迁移,默认false.
    spring.flyway.ignore-failed-future-migration = false
    
    # 当初始化好连接时要执行的SQL.
    spring.flyway.init-sqls =
    
    # 迁移脚本的位置,默认db/migration.
    # 这个配合Profile,能给与不同的环境不同的测试数据
    spring.flyway.locations =  classpath:/db/migration,classpath:/db/migration_development
    
    # 是否允许无序的迁移,默认false.
    spring.flyway.out-of-order = false
    
    # 迁移时是否校验,默认为true
    spring.flyway.validate-on-migrate = true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    配置的描述如上,特别要注意的是spring.flyway.clean-on-validation-error的选项。它是用来方便开发环境时调试数据库用的,当更改了本地的迁移脚本后,flyway会自动感受到,就会全面将所有的数据库清空,重新导入schema。但是切勿在生产环境中使用,生产环境一旦发现迁移脚本的hash值与flyway_schema_history的hash值不一致就清空数据库,这显然会产生重大的事故。

    但是由于在生产环境也可能容易导入开发环境的配置,所以clean-on-validation-error最好永远都设置为false。

    spring.flyway.locations =  classpath:/db/migration,classpath:/db/migration_development
    
    • 1

    这个属性也好用,可以支持多个locations。那么我们可以为不同的development环境,production环境设置部分不同的迁移脚本,例如development环境相比production环境会多一些默认的测试数据。

    7.2、新项目引入flyway

    # 是否开启flywary,默认true.
    spring.flyway.enabled = true
    
    # 迁移时是否校验,默认为true
    spring.flyway.validate-on-migrate = true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    7.3、旧项目引入flyway

    # 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
    spring.flyway.baseline-on-migrate = true
    
    # baseline的版本号,默认为1.0
    spring.flyway.baseline-version = 0.9
    
    • 1
    • 2
    • 3
    • 4
    • 5

    对于已有的项目,在启动的时候就需要打开baseline-on-migrate,并设置baseline的版本号。那么首次启动项目时,就会执行一次baseline,赋值baseline的版本号,然后执行该版本号之后的迁移脚本了。

    8、总结&参考代码

    Flyway相对Liquibase的好处在于,用原生的SQL语句写迁移脚本,简单易理解。缺点当然就是它无法理解SQL语句的意义,造成undo操作和回滚操作都不能很好地支持。

    参考源码:https://pan.baidu.com/s/17gj1PK_byVGRaBHyfRV3MQ
    提取码:kgad

  • 相关阅读:
    《web课程设计》使用HTML+CSS制作大学生校园二手交易网站
    TensorRT8.2.1.8基于Docker容器快速安装
    GD32_ADC采样+DMA多通道扫描传输
    Android.bp常用语法和预定义属性
    tomcat部署、tomcat虚拟主机及tomcat多实例、tomcaty优化
    高薪程序员&面试题精讲系列129之你熟悉哪些版本控制工具?你知道哪些Git命令?fetch与pull有哪些区别?
    Windowds10安装LDAP服务器和客户端及遇到问题的整理
    css自学框架之消息弹框
    Windows 内网渗透之横向渗透
    基于MATLAB的变换编码的设计与实现
  • 原文地址:https://blog.csdn.net/qq_42038623/article/details/126346931