乐趣区

关于flyway:器篇Flyway-Flyway-概述

一. 引言来

在软件我的项目开发工程中,一般来说我的项目都是几个开发人员齐头并进的,经常遇到的事件是,大家都同时提交数据库表批改语句后,并不告知其它人,或者几个开发人员同时批改一个表构造,导致其他人运行我的项目出错。

还有在我的项目上线运行过程中,经常会因为治理数据库表构造或者表数据版本而发愁,甚至有的时候还不得不为生产数据做迁徙操作。

以上的问题,咱们个别的操作都是约定 + 脚本,但效率不高,并且经常会因为版本抵触,不得不手动 merge。这个时候一个麻利工具,用于数据库的移植的Flyway 利用而生,它的次要用于在你的利用版本一直降级的同时,降级你的数据库构造和外面的数据。

二、介绍来

1. Flyway 的特色

Flyway 大受欢迎是因为它具备如下劣势:

  • 简略 很是容易装置和学习,同时迁徙的形式也很容易被开发者承受。
  • 专一 专一于用作数据库迁徙、版本控制而并无其它副作用。
  • 弱小 专为间断交付而设计,让 Flyway 在应用程序启动时迁徙数据库。

2. Flyway 的工作机制

Flyway 须要在 DB 中先建设一个 metadata 表 (缺省表名为 flyway_schema_history), 在该表中保留着每次 migration(迁徙)的记录, 记录蕴含 migration 脚本的版本号和 SQL 脚本的 checksum 值。下图示意了多个数据库版本。

对应的 metadata 表记录:spring

installed_rank version description type script checksum installed_by installed_on execution_time success
1 1 Initial Setup SQL V1__Initial_Setup.sql 1996767037 axel 2016-02-04 22:23:00.0 546 true
2 2 First Changes SQL V2__First_Changes.sql 1279644856 axel 2016-02-06 09:18:00.0 127 true

Flyway 扫描文件系统或应用程序的类门路读取 DDLDML 以进行迁徙。依据metadata 表进行查看迁徙。** 若是脚本申明的版本号小于或等于标记为以后版本的版本号之一,将疏忽它们。其余迁徙是待处理迁徙:可用,但未利用。最初按版本号对它们进行排序并按程序执行 并将执行后果写入 metadata 表。

对应的 metadata 表记录:数据库

installed_rank version description type script checksum installed_by installed_on execution_time success
1 1 Initial Setup SQL V1__Initial_Setup.sql 1996767037 axel 2016-02-04 22:23:00.0 546 true
2 2 First Changes SQL V2__First_Changes.sql 1279644856 axel 2016-02-06 09:18:00.0 127 true
3 2.1 Refactoring JDBC V2_1__Refactoring axel 2016-02-10 17:45:05.4 251 true

Flyway 反对命令行(须要下载命令行工具)和 Java Api,也反对构建工具 MavenGradle。这里咱们将眼光放在 Java Api 上。

3. Flyway 的规定

Flyway 是如何比拟两个 SQL 文件的前后程序呢?它采纳 采纳左对齐准则, 缺位用 0 代替

1.0.1.1 比 1.0.1 版本高

1.0.10 比 1.0.9.4 版本高

1.0.10 和 1.0.010 版本号同样高, 每一个版本号局部的前导 0 会被疏忽

FlywaySQL 文件分为 VersionedRepeatableUndo 三种:

  • Versioned 用于版本升级, 每一个版本有惟一的版本号并只能执行一次。
  • Repeatable 可反复执行, 当 Flyway检测到 Repeatable 类型的 SQL 脚本的 checksum 有变更, Flyway 就会从新利用该脚本. 它并不用于版本更新, 这类的 migration 老是在 Versioned 执行当前才被执行。
  • Undo 用于撤销具备雷同版本的版本化迁徙带来的影响。可是该回滚过于粗犷,过于机械化,通常不举荐应用。通常倡议应用 Versioned 模式来解决。

这三种的命名规定以下图:

  • Prefix 可配置,前缀标识,默认值 V 示意 Versioned, R 示意 Repeatable, U 示意 Undo
  • Version 标识版本号, 由一个或多个数字形成, 数字之间的分隔符可用点 . 或下划线 _
  • Separator 可配置, 用于分隔版本标识与形容信息, 默认为两个下划线 __
  • Description 形容信息, 文字之间可能用下划线 _ 或空格 “ 分隔
  • Suffix 可配置, 后续标识, 默认为 .sql

4.flyway 命令行

flyway 提供命令行工具, 罕用的命令包含:

  • Clean: 删除所有创立的数据库对象, 包含用户、表、视图等. 留神不要在生产库上执行 clean 操作.
  • Migrate: 对数据库顺次利用版本更改.
  • Info: 获取目前数据库的状态. 那些迁徙曾经实现, 那些迁徙待实现. 所有迁徙的执行工夫以及后果.
  • Validate: 验证已 Apply 的脚本是否有变更, Flyway 的 Migration 默认先做 Validate.
  • Baseline: 依据现有的数据库构造生成一个基准迁徙脚本.
  • Repair: 修复命令尽量不要应用, 修复场景有: 1. 移除失败的 migration 记录. 2. 曾经利用的 SQL 脚本被批改, 咱们想从新利用该 SQL 脚本.

maven 插件

           <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <configuration>
                    <user>${flyway.user}</user>
                    <password>${flyway.password}}</password>
                    <url>${flyway.url}</url>
                </configuration>
            </plugin>

5.flyway 最佳实际

1.SQL 的文件名

开发环境和生产环境的 migration SQL 不共用. 开发过程往往是多人合作开发, DB migration 也绝对比拟频繁, 所以 SQL 脚本会很多. 而生产环境 DB migration 往往由 DBA 实现, 每次降级通常须要提交一个 SQL 脚本.

DDL DML 离开

  • 开发环境 SQL 文件倡议采纳工夫戳作为版本号, 多人一起开发不会导致版本号争用, 同时再加上生产环境的版本号, 这样的话, 未来手工 merge 成生产环境 V1.2d migration 脚本也比拟不便, SQL 文件示例:

    • V20180317.14.59__V1.2_Add_SomeTables.sql
    • V20180317.14.59__V1.0.1_ProjectName_{Feature|fix}_Developer_Description.sql
  • 生产环境 SQL 文件, 应该是手动 merge 开发环境的 SQL 脚本, 版本号依照失常的版本, 比方 V2.1.5_001__Unique_User_Names.sql
2. migration 后的 SQL 脚本不应该再被批改.
3. spring.flyway.outOfOrder 取值 true /false

对于开发环境, 可能是多人合作开发, 很可能先 apply 了本人本地的最新 SQL 代码, 而后发现其余共事新近时候提交的 SQL 代码还没有 apply, 所以 开发环境应该设置 spring.flyway.outOfOrder=true, 这样 flyway 将能加载漏掉的老版本 SQL 文件; 而生产环境应该设置 spring.flyway.outOfOrder=false

4. 多个零碎专用要 DB schema

很多时候多个零碎专用一个 DB schema , 这时候应用 spring.flyway.table 为不同的零碎设置不同的 metadata 表, 缺省为 flyway_schema_history

5. 尽量配置.sql 到 filesystem,而不是我的项目工程下, 起因是不便替换,并不占用 jar 包大小
6. 不举荐应用 Undo,太过粗犷

7. 理论工程配置和目录

  # flyway 配置内容,对应 FlywayAutoConfiguration.FlywayConfiguration 配置项
  flyway:
    enabled: true # 开启 Flyway 性能
    cleanDisabled: true # 禁用 Flyway 所有的 drop 相干的逻辑,避免出现跑路的状况。locations: # 迁徙脚本目录
      - classpath:db/migration/dev # 配置 SQL-based 的 SQL 脚本在该目录下
    check-location: false # 是否校验迁徙脚本目录下。如果配置为 true,代表须要校验。此时,如果目录下没有迁徙脚本,会抛出 IllegalStateException 异样
    url: jdbc:mysql://192.168.8.94:3399/flyway-test?useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库地址
    user: root # 数据库账号
    password: 1234123 #数据库明码
    baseline-version: 1.0
    baseline-description: "baseline"
    encoding: UTF-8
    out-of-order: true # 是否答应不按程序迁徙 开发倡议 true  生产倡议 false
    # 如果指定 schema 蕴含了其余表, 但没有 flyway schema history 表的话, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令.
    # 设置 spring.flyway.baseline-on-migrate 为 true 后, flyway 将在须要 baseline 的时候, 主动执行一次 baseline.
    baselineOnMigrate: true
    table: flyway_schema_history

我的项目工程目录

三、扩大来

除开 Flyway, 还有其它的数据库迁徙和版本控制工具,例如弱小的Liquibase。两者具体的差别,在后续的文章论述。在以往的教训中,小我的项目,整体变动不大的用Flyway,而大利用和企业应用用Liquibase 更适合。

退出移动版