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 ...
随机推荐
- 浅谈HTTP中GET和POST请求方式的区别
浅谈HTTP中GET和POST请求的区别 HTTP认知: HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议.HTTP的底层是TCP/IP.所以GET和POST的底层也是TCP/IP,也 ...
- 第一个Django demo
平台:Pycharm Django 使用 Pycharm 进行开发,需要提前在 Pycharm 中(File > Settings > Project: Python > Proje ...
- 六、Django之表单和类视图-Part 4
一.表单form 为了接收用户的投票选择,我们需要在前端页面显示一个投票界面.让我们重写先前的polls/detail.html文件,代码如下: <h1>{{ question.quest ...
- 私有云搭建:树莓派+kodexplorer可道云,几步搞定!
目前蒲公英异地组网则是推出了树莓派1.0软件客户端.无需公网IP!简单60秒设置!轻松远程访问树莓派!实现远程登录.远程配置.远程访问服务.传输数据等等操作.例如:蒲公英树莓派1.0软件客户端+可道云 ...
- ubuntu HackRF One相关环境搭建
本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...
- ubuntu16.04 CUDA, CUDNN 安装
这次介绍的是使用 tensorflow1.8, cuda9.0, cudnn7.0的版本 https://developer.nvidia.com/cuda-90-download-archive 下 ...
- python json模块使用详情
python其他知识目录 #json.数据交换用到json文件.json是特殊的字符串.访问网站,返回的就是json 1.json简介: 定义:JSON(JavaScript Object Notat ...
- bc命令详解
基础命令学习目录首页 原文链接:https://www.cnblogs.com/lovevivi/p/4359296.html 最近经常要在linux下做一些进制转换,看到了可以使用bc命令,如下: ...
- 3.控制hive map reduce个数
参考: https://blog.csdn.net/wuliusir/article/details/45010129 https://blog.csdn.net/zhong_han_jun/arti ...
- max number of clients reached Redis测试环境报错
现象:测试服务是去redis循环取数据,早上发现服务挂了,手动登陆redis 无法输入命令,报错:max number of clients reached Redis