Flyway学习笔记
Flyway做为database migration开源工具,功能上像是git、svn这种代码版本控制。google搜索database migration,或者针对性更强些搜索database migration java,会有其它的framework、tool、甚至aws的service。因为项目使用到了flyway,而且确实google中排第一位的搜索结果就是flyway,那就之后有机会再与其它方案做比较,先对flyway做下学习笔记。
0.支持的数据库
支持数据库有 Oracle, SQL Server, SQL Azure, DB2, DB2 z/OS, MySQL (including Amazon RDS), MariaDB, Google Cloud SQL, PostgreSQL (including Amazon RDS and Heroku), Redshift, Vertica, H2, Hsql, Derby, SQLite, SAP HANA, solidDB, Sybase ASE and Phoenix。
1. 安装
1.1 Cli
从官网下载压缩包:https://flywaydb.org/documentation/commandline/。
解压后cd到目录下,就可以直接执行flyway。解压后的文件夹结构如下图:
如果操作数据库,需要先在/conf/flyway.conf文件中做下配置,主要是对flyway.url、flyway.user和flyway.password(如何支持针对多个database,尚未做实验,待论),注释中给出了url的详细格式,可以根据环境自行添加。
1.2 Spring Integrating
2 |
<bean id="flyway" class="org.Flyway.core.Flyway" init-method="migrate" depends-on="dataSource"> |
3 |
<property name="dataSource" ref="dataSource" /> |
4 |
<property name="locations" value="postgresql/db/migrations/" /> |
5 |
</bean> |
每次app启动的时候,确切说在flyway的bean初始化的时候,就会自动检测扫描locations路径下的文件。locations文件夹中的文件,按照flyway官方默认的命名方式,就是用Vx_x__description.sql。sql文件,还有实现JdbcMigration接口生成的class文件(后文描述),都会列在schema_version表中,作为版本控制的原子项。比如在部署环境,只要war包中locations中的sql文件改变了,那么数据库就会做出相应的调整。
2. 配置
2.1 flyway.conf
flyway.conf:加载配置文件遵循下列顺序,并且后面加载的配置会覆盖前面的配置。
· <install-dir>/conf/flyway.conf
· <user-home>/flyway.conf
· <current-dir>/flyway.conf
文件中除了配置数据库信息,还能对比如prefix、separator、suffix做定义,默认prefix是V(执行一遍,并且版本号唯一,如果有重复就会报错)或R(重复执行,不需要版本号),separator是双下划线__,suffix是.sql。
官方文档中给出了SQL migration执行过程中扫描文件的顺序,即classpath:db/migration或者file system: 自定义文件夹。或者在执行flyway migration的时候使用-X参数,就能看到执行流程,这个确实有助于理解flyway的workflow。
2.2 drivers
flyway使用JDBC连接数据库,在drivers文件夹下有默认的几种,
· SQL Server (jTDS)
· MySQL
· MariaDB
· PostgreSQL
· Redshift
· H2
· Hsql
· Derby
· SQLite
如果要操作其它数据库,需要手动添加JDBC的driver到此文件夹下。
如果是用Spring集成,那么需要特别指定用的drivers是哪一个,比如org.postgresql.Driver
3. 基本指令
一共就6个基本指令:migrate、clean、info、validate、baseline、repair。强烈推荐在使用初期使用-X参数,log会显示flyway自己的业务逻辑。
4. 处理逻辑
4.1 schema_version
Flyway会生成一个表schema_version来记录文件的执行情况,关于生成与修改这个表的相关文件,在lib文件夹中有一个jar包flyway-core-2.1.1.jar,可以用WinZip打开,在下图位置示例了生成表的createMetaDataTable.sql文件,以及操作相关的class文件。
schema_version表中记录的每个脚本文件的执行情况,官方文档上有pending、success、failed、outdated和future,我还没有出现failed和outdated,不过有ignored,可能是因为用了V0。
4.2 文件处理逻辑
做为测试,我使用的执行步骤如下:
1. V1__create放入文件夹,migrate成功
2. V0__drop放入文件夹,migrate,结果是ignored
3. V0改为V1,numeric冲突,报错了
4. V0__drop改为V1_1__drop,migrate,执行成功
5. V1_1_drop删除,migrate,在schema_version表中,V1_1_drop状态为future,说明表中不会自己删除那些文件已不存在的item,而且drop掉的表不会再被创建,因为在schema_version表中V1__create的状态已经是success了。
5. FAQ
其中几个为官方文档的翻译,里面有些问题虽然没碰到,不过先自己翻译一遍加深理解。
对于降级操作(downgrade scripts/downward migrations)的支持
Flyway does NOT support downgrade scripts.
While the idea of downgrade scripts (popularized by Rails Migrations) is a nice one in theory, unfortunately it breaks down in practice. As soon as you have destructive changes (drop, delete, truncate, ...), you start getting into trouble. And even if you don't, you end up creating home-made alternatives for restoring backups, which need to be properly tested as well.
Flyway不支持降级的脚本:
一旦执行了诸如drop、delete、truncate这样的清除性动作,从之前的实验操作结果,我理解并不是说flyway不会甚至不能执行降级操作,毕竟drop、delete、truncate只是一些指令,flyway本身并没有能力看出来是哪些操作,这个回答应该是想说,最好不要做诸如此类的清除性动作,否则麻烦就来了,除非之前已经做了充分的备份以恢复数据。
Downgrade scripts assume the whole migration failed.
A migration can fail at any point. If you have 10 statements, it is possible for the 1st, the 5th, the 7th or the 10th to fail. There is simply no way to know in advance. Downgrade scripts are written to roll back an entire migration. This renders them effectively useless, even for non-destructive changes.
Migration执行失败可能发生在任何一个脚本,而降级操作相当于是在之前已经完成的基础上,那么如果前面的脚本执行失败,那么后面的操作就不会起作用,即便不是消除性操作。
我理解答案是想说明migration执行成功与否具有不确定性,而且版本号越高不确定性越强,因为会依赖先前的执行结果。
Maintain backwards compatibility between the DB and all versions of the code currently deployed in production.
This way a failed migration is not a disaster. The old version of the application is still compatible with the DB, so you can simply roll back the application code, investigate, and take corrective measures.
要确保数据库与线上各个版本代码的兼容性,才不会因为一次失败的migration脚本而造成重大损失。而且当真正执行失败的时候,也可以恢复回老版本的代码,再对错误做出修正。
A much better solution is a proper, well tested, backup and restore strategy.
It is independent of the database structure, and once it is tested and proven to work, no migration script can break it. For optimal performance, and if your infrastructure supports this, we recommend using the snapshot technology of your underlying storage solution. Especially for larger data volumes, this can be several orders of magnitude faster than traditional backups and restores!
这里是推荐在条件允许的情况下,用快照对已上线的系统做数据备份,说是比传统的数据备份与恢复要快。
如何做好热修复?
比如说现在已经上线的是版本7,正在开发的是版本8,而且版本8在DB schema上有些改动。此时有些bug导致需要对版本7做些热修复,也涉及到了schema的改动。
一般来说,虽然代码有多个分支,不过schema不会。所以可以将热修复的脚本标号为7.1,并且适用于修复版本7,和新的版本8。这样在版本8真正上线的时候,也会按照7、7.1、8的顺序执行脚本。
如果上述方案不行,还可以用outOfOrder(在flyway.conf有这个参数)属性,这样就可以允许不全部按照从小到大的顺序执行migration,也就是比schema_version中记录的最大值小的脚本,也能够被执行。
多个节点能够并行执行migration吗?
当然可以!Flyway使用数据库锁机制(locking technology of your database)来协调多个节点,从而保证多套应用程序可同时执行migration,而且集群控制也可做配置。
如果migration执行失败,会有回滚吗?
Flyway在不同的事物中执行migration,如果失败,那么事物就会回滚。不过不幸的是,现在只有DB2、PostgreSQL、Derby还有个别SQL Server扩展支持事物内的DDL。Other databases such as Oracle will implicitly sneak in a commit before and after each DDL statement, drastically reducing the effectiveness of this roll back. (没看太懂得一句)。一个可行的办法就是一个migration只包含单个DDL,只不过这样做比较累。
Flyway是否支持多schema?
当然支持!以下有几种策略来处理多schema的情况:
如果有多个相异的schema,可以用flyway的loop并且设置与schema对应的flyway.schemas。
如果schema的生命周期相同,那么可以只用一个flyway实例,设置flyway.schemas值为所有schemas以逗号隔开的字符串。所有的schema将只用到一个schema_version来记录脚本执行情况。(不知道此时schema_version表中会不会有专门的一列显示schema的名称)
如果schemas的生命周期不同,那就要启动多个flyway实例,每个实例处理自己的schema和metedata table,注意要把脚本分开放。
Flyway学习笔记的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
随机推荐
- JAVA基础 XML生成与解析和String包装类下 .replace方法的使用以及char和字符序列的使用场景
ptLink0.setText(arbu.getPtLink().replace("&","&")); // 如果像 '&','& ...
- Package设计2:增量更新
SSIS 设计系列: Package设计1:选择数据类型.暂存数据和并发 Package设计2:增量更新 Package 设计3:数据源的提取和使用暂存 一般来说,ETL实现增量更新的方式有两种,第一 ...
- Python中的注释
1.1 注释的目的 通过用自己熟悉的语言,在程序中对某些代码进行标注说明,这就是注释的作用,能够大大增强程序的可读性. 1.2 注释的分类 1.2.1 单行注释 以#开头,#右边的所有东西当做说明,而 ...
- jenkins+Gitlab持续集成环境配置教程
环境简介: Jenkins 2.156(本地win10) GitLab Enterprise Edition 10.1.4-ee (远程服务器) Apache Ant 1.9.13 (本地win10) ...
- 旧的 .NET Core 项目重新打包出现提示版本不对问题
错误提示 当电脑更新 VS2017 版本后,如果同时有新的 .NET Core SDK 更新,打开旧的项目重新打包,可能会报这样的错误 NETSDK1061: 项目是使用 Microsoft.NETC ...
- linux 开机报错,error grub_efi_find_mmap_size not find
开机报错,差点以为要重装系统了 搜到了官方的重建引导的教程 修复了错误 https://wiki.manjaro.org/index.php/Restore_the_GRUB_Bootloader#F ...
- Unity 实现一个简单的 TPS 相机
效果如下: 代码如下: public class TPSCamera : MonoBehaviour { /// <summary> /// 目标对象 /// </summary&g ...
- MySQL(MariaDB)基础之一:编译安装
一.cmake介绍 cmake的重要特性之一是其独立于源码的编译功能,即编译工作可以在另一个指定的目录中而非源码目录中进行,这可以保证源码目录不受任何一次编译影响,因此在同一个源码树上可以进行多次不同 ...
- VOT工具操作指南(踩过的坑)
为了运行在VOT里DaSiamRPN,配置了很久环境,我电脑的配置是Ubuntu16.04+MatlabR2018a+pytorch0.3. 下面是一些从网上整理的操作步骤: 1.首先是工具箱的下载: ...
- Vuejs 使用 lib 库模式打包 umd 解决 NPM 包发布的问题
由于升级了 v0.2 版 GearCase 使用打包工具从 parcel 更换成 vue-cli 3.x.因此打包后发布 NPM 包的方式与之前有很大的差异,这也导致了在发布完 GearCase v0 ...