目录
为什么要进行数据库迁移?
Flyway的运作方式
Flyway的优势是什么?
Flyway使用简介
集成SpringBoot
常见问题
Java代码实现迁移
官网地址: Homepage - Flyway
Flyway是一个开源数据库迁移工具。与配置相比,它极力主张简单性和约定性。
它仅基于7个基本命令: 迁移, 清理, 信息, 验证, 撤消, 基线和 修复。
可以使用SQL (支持特定于数据库的语法(例如PL / SQL,T-SQL等))或Java (用于高级数据转换或处理LOB)编写迁移。
它具有一个命令行客户端。如果您使用的是JVM,建议您在应用程序启动时使用Java API(也适用于Android)迁移数据库。或者,您也可以使用Maven插件 或Gradle插件。
如果还不够,那么可以 使用Spring Boot,Dropwizard,Grails,Play,SBT,Ant,Griffon,Grunt,Ninja等插件!
支持的数据库包括 Oracle, SQL Server(包括Amazon RDS和Azure SQL数据库), Azure Synapse(以前称为数据仓库), DB2, MySQL(包括Amazon RDS,Azure数据库和Google Cloud SQL), Aurora MySQL, MariaDB, Percona XtraDB集群, TestContainers, PostgreSQL(包括Amazon RDS,Azure数据库,Google Cloud SQL和Heroku), Aurora PostgreSQL, Redshift, CockroachDB, SAP HANA, Sybase ASE, Informix, H2, HSQLDB, Derby, Snowflake, SQLite和 Firebird。
为什么要进行数据库迁移?
首先,让我们从头开始,并假设我们有一个名为Shiny的项目,其主要交付项目是一个名为Shiny Soft的软件,该软件连接到名为Shiny DB的数据库。
代表这一点的最简单的图可能看起来像这样:
我们拥有我们的软件和数据库。伟大的。这很可能就是您所需要的。
但是在大多数项目中,这种简单的世界观很快就会转化为:
现在,我们不仅要处理我们环境的一个副本,还要处理几个环境。这提出了许多挑战。
我们非常擅长在代码方面解决它们。
- 现在,版本控制已普遍存在,并且每天都有更好的工具。
- 我们拥有可复制的版本和持续集成。
- 我们有明确定义的发布和部署过程。
但是数据库呢?
不幸的是,我们在那里做得不好。许多项目仍然依赖手动应用的sql脚本。有时甚至不行(这里或那里的快速sql语句可解决问题)。很快出现了许多问题:
- 该计算机上的数据库处于什么状态?
- 此脚本是否已被应用?
- 之后,生产中的快速修复是否已在测试中得到应用?
- 如何设置新的数据库实例?
这些问题的答案通常是:我们不知道。
数据库迁移是重新获得对这一混乱局面的控制的好方法。
他们使您能够:
- 从头开始创建数据库
- 随时清楚数据库所处的状态
- 确定性地从当前数据库版本迁移到较新版本
Flyway的运作方式
最简单的情况是将Flyway指向空数据库。
它将尝试找到其架构历史记录表。由于数据库为空,因此Flyway找不到它, 而是创建它。 现在,您有了一个数据库, 默认情况下有一个名为flyway_schema_history的空表:
该表将用于跟踪数据库的状态。
之后,Flyway将立即开始扫描文件系统或应用程序的类路径以进行迁移。它们可以用Sql或Java编写。
然后,根据迁移的版本号对迁移进行排序并按顺序应用:
应用每个迁移时,架构历史记录表将相应更新:
flyway_schema_history
installed_rank | 版本 | 描述 | 类型 | 脚本 | 校验和 | 已安装 | 已安装 | 执行时间处理时间 | 成功 |
1个 | 1个 | 初始设置 | 的SQL | V1__Initial_Setup.sql | 1996767037 | 轴 | 2016-02-04 22:23:00.0 | 546 | 真的 |
2个 | 2个 | 最初的变化 | 的SQL | V2__First_Changes.sql | 1279644856 | 轴 | 2016-02-06 09:18:00.0 | 127 | 真的 |
通过元数据和初始状态,我们现在可以讨论迁移到较新的版本。
Flyway将再次扫描文件系统或应用程序的类路径以进行迁移。对照架构历史记录表检查迁移。如果它们的版本号小于或等于标记为当前版本的版本号之一,则将忽略它们。 其余迁移是待处理的迁移:可用,但未应用。
然后按版本号对它们进行排序并按顺序执行:
该模式历史表的更新,因此:
flyway_schema_history
installed_rank | 版本 | 描述 | 类型 | 脚本 | 校验和 | 已安装 | 已安装 | 执行时间处理时间 | 成功 |
1个 | 1个 | 初始设置 | 的SQL | V1__Initial_Setup.sql | 1996767037 | 轴 | 2016-02-04 22:23:00.0 | 546 | 真的 |
2个 | 2个 | 最初的变化 | 的SQL | V2__First_Changes.sql | 1279644856 | 轴 | 2016-02-06 09:18:00.0 | 127 | 真的 |
3 | 2.1 | 重构 | JDBC | V2_1__重构 | 轴 | 2016-02-10 17:45:05.4 | 251 | 真的 |
就是这样!每当需要发展数据库时,无论是结构(DDL)还是参考数据(DML),都只需创建一个版本号高于当前版本的新迁移即可。下次Flyway启动时,它将找到它并相应地升级数据库。
Flyway的优势是什么?
Flyway使用简介
集成SpringBoot
1.添加依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.1.1</version>
</dependency>
添加插件:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>5.1.1</version>
</plugin>
2.命名规范 sql 脚本存放目录:src/main/resources/db/migration 对应一个程序版本的多个脚本,从1开始,比如1.0.9版本,有多个任务:张三负责a任务(tapd号为1111111),李四负责b任务(tapd号为222222),他们的任务都涉及到db更新他们会分别创建两个脚本: V1.0.9.0.1__1111111.sql V1.0.9.0.2__222222.sql 说明:V大写,中间是两个下划线(__)
常见问题
1、可以基于环境变量,实现不同的环境,做不同的初始化脚本吗? 基于我们的配置中 心,可以对flyway.locations配置进行修改,不同环境的初始化脚本可以放到不同的目录下。
2、初始化数据过程会发生错误回滚? 每 一个sql 文件会有 一个单独的事物,如果单个文件中发 生错误,单个文件的操作会回滚, 比如有1、2、3个 文件,第 二个文件发生错误,第二个文件所有操作将会回滚,第三个文件不会执行。但: Unfortunately, today only DB2, PostgreSQL, Derby, EnterpriseDB and to a certain extent SQL Server support DDL statements inside a transaction。 所以,建议不要把ddl 文件和dml语句句放到同 一个文件 里,避免不必要的麻烦。
3、多个节点能够并行执行migration吗? 当然可以!Flyway使用数据库锁机制(locking technology of your database)来协调多个节点,从而保证多套应用程序可同时执行migration,而且集群控制也可做配置。
4、迁移失败版本号处理
flyway Schema 'order' contains a failed migration to version 0.2.4 !
到对应的schema_version_order 表删除失败记录退回修改表的更改。
Java代码实现迁移