轻松上手数据库版本管理工具Flyway

Flyway 是一个用Java编写的开源数据库版本管理工具,或者说是数据库结构变更工具,旨在帮助开发和运维更容易地管理数据库演进过程中的各个版本。它的源代码在 github 上。

简介

在开发过程中,数据库是不断向前演进的,可以说是拥有“版本”这个概念。通常当在生产环境部署新代码的时候,会由开发或者DBA来做数据库结构变更的操作。当数据库较小,环境数量少的时候,人工操作比较有把握,直接就人肉来做结构变更了。可要是在数据库复杂、环境数量多(开发、测试、预发布、生产……)的情况下,人工处理这样的事就开始有些令人担心了。如何保证所有环境的数据库结构是一致的?如何知道当前环境的数据库是哪个状态?如何知道生产环境的一个关于数据库的hotfix是否也在预发布环境中执行了?Flyway就是用来解决这样的问题的工具。它的原理非常简单,就是在数据库中创建一张自己用的表,例如schema_version,在里面存放数据库当前的状态,以此来管理数据库的版本。Flyway提供了 命令行 、 API 、 Maven 、 Gradle 、 Ant 、 SBT 等各种方式,来让我们更容易将其与自己的项目结合。类似的工具还有 Liquibase 、 dbdeploy 等。

本文将会用Docker来创建一个mysql的实例,用Maven来创建一个包含数据库的Java项目,并使用Flyway来进行版本管理。

准备环境

首先请自行安装Docker、Java、Maven和喜欢的IDE。我用的是 Intellij IDEA社区版。我用Vagrant启动了一台已经安装过Docker的Ubuntu虚拟机,它的IP是 192.168.33.88 ,可以用以下命令来直接启动mysql容器来提供数据库服务并创建ggg数据库:

docker run -d --net=host --name=mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.12
docker exec -it mysql mysql -uroot -p123456 -e 'create database ggg;'

接下来新建一个Maven工程helloFlyway:

mvn archetype:generate -B \
        -DarchetypeGroupId=org.apache.maven.archetypes \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DarchetypeVersion=1.1 \
        -DgroupId=org.ggg.flyway \
        -DartifactId=helloFlyway \
        -Dversion=1.0-SNAPSHOT \
        -Dpackage=org.ggg.flyway

在 helloFlyway/pom.xml 里加入flyway的maven插件和mysql-connector-java的依赖(别忘了根据你自己的数据库来配置jdbc):

pom.xml
<project ...>
    ...
    <build>
        <plugins>
            <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <version>4.0.3</version>
                <configuration>
                    <url>jdbc:mysql://192.168.33.88:3306/ggg</url>
                    <user>root</user>
                    <password>123456</password>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.38</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

接下来创建一个数据库版本1的文件:

cd helloFlyway
mkdir -p src/main/resources/db/migration/
cat << EOF > src/main/resources/db/migration/V1__Create_person_table.sql
create table PERSON (
    ID int not null,
    NAME varchar(100) not null
);
EOF

工程创建好并用intellij导入后,应该是这样的:

版本管理

使用以下命令来运行flyway:

mvn flyway:migrate

出现 BUILD SUCCESS 就说明数据库结构变更已经完成了。我们可以登录到数据库看一看:

docker exec -it mysql mysql -uroot -p123456

运行以下sql就可以看到flyway确实已经起作用了:

USE ggg
SHOW TABLES;
SELECT * FROM schema_version;

而表schema_version里面也有了一条记录。接下来再创建一个数据库版本2的文件:

cat << EOF > src/main/resources/db/migration/V2__Add_people.sql
insert into PERSON (ID, NAME) values (1, 'Axel');
insert into PERSON (ID, NAME) values (2, 'Mr. Foo');
insert into PERSON (ID, NAME) values (3, 'Ms. Bar');
EOF

再次用同一条命令来运行flyway:

mvn flyway:migrate

就会看到日志里显示 Current version of schema gggggg: 1 和 Migrating schema gggggg to version 2 - Add people 。如果我们重复运行 mvn flyway:migrate ,就会看到 Schema gggggg is up to date. No migration necessary 。现在查看一下两张表:

SELECT * FROM PERSON;
SELECT * FROM schema_version;

PERSON表里已经有了 V2__Add_people.sql 里的三条记录,而schema_version表里,就可以看到现在的版本为2。通过这样的方式,就可以管理数据库的版本了。

历史数据库

如果数据库里已经有历史数据了,那就会稍微麻烦一点儿。我们来试试看,首先改造一下ggg数据库:

RENAME TABLE PERSON TO STUDENT;
DROP TABLE schema_version;

这样一来,数据库的版本便被清空,PERSON表也变成了STUDENT表。如果直接运行 mvn flyway:migrate 会报错: org.flywaydb.core.api.FlywayException: Found non-empty schema gggggg without metadata table 。这时候需要用到另一个命令:

mvn flyway:baseline

上面的 baseline 命令会以现在的数据库结构为基础,创建一张schema_version表,标明现在的版本是1。接着运行 mvn flyway:migrate 还会报错: Migration of schema ggg to version 2 - Add people failed 。这是因为数据库现在是版本1,所以会忽略 V1__Create_person_table.sql 而直接执行 V2__Add_people.sql ,而 V2__Add_people.sql 依赖于 V1__Create_person_table.sql 里创建的PERSON表,所以失败了。解决的方法也很简单,改变两个sql文件的版本即可:

mv src/main/resources/db/migration/V1__Create_person_table.sql src/main/resources/db/migration/V1_1__Create_person_table.sql
mv src/main/resources/db/migration/V2__Add_people.sql src/main/resources/db/migration/V1_2__Add_people.sql
mvn flyway:migrate

Flyway的命名规范如下:以 V 开头, .sql 结尾,版本号可以使用 . 或者 _ ,版本号和描述之间用两个下划线 __ 分开。要是执行成功,但是却看不到PERSON表,那很可能是因为schema_version表里的版本已经是一个 错误的 版本2了,运行repair之后再重新migrate即可:

mvn flyway:repair
mvn flyway:migrate
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值