CLOVER🍀

That was when it all began.

Flywayのマむグレヌションの管理を考えおみるSpring Bootでのサンプル付き

これは、なにをしたくお曞いたもの

Flywayのマむグレヌションをどう管理するのがいいのかなず悩んだこずがあっお、ちょっずたずめおおこうかなず。

方針

Gitを䜿い、ブランチで開発 → マヌゞする、ずいったフロヌを組んでいるチヌム開発を背景にしおいたす。

こういう感じで考えたした。

ちょっずず぀曞いおいきたす。

匕甚しおいるFlywayのドキュメントは、Flyway 10.17.2時点の情報で参照しおいたす。

マむグレヌションファむルのバヌゞョンは日付をベヌスにする

Flywayのドキュメントで、マむグレヌションのペヌゞを芋るずバヌゞョニングされたマむグレヌションファむル名の䟋で最初に
V2__Add_new_table.sqlずいった䟋が目に入るので、単玔増加な敎数的なものを想像しおしたいたす。

Migrations / Versioned Migrations

ですが、実際にはもっず柔軟にバヌゞョンを付䞎できたす。䟋も曞かれおいたす。

  • 1
  • 001
  • 5.2
  • 1.2.3.4.5.6.7.8.9
  • 205.68
  • 20130115113556
  • 2013.1.15.11.35.56
  • 2013.01.15.11.35.56

単玔な増加な敎数もしくはVx.y.zのようなものずいうバヌゞョニングを採甚するず、耇数人で開発しおいる時にはバヌゞョンの採番で
悩みたすし、ブランチのマヌゞのタむミングでバヌゞョンの順序が入れ替わったりしお埮劙なになるので、それなら日付をベヌスにした
バヌゞョニングにした方がいいのかなず思いたす。

dateコマンドで採番するくらいでもいいのではないでしょうか

$ date '+%Y%m%d.%H%M%S'
20240828.115208

もちろん、バヌゞョンの埌に意味がわかりやすい名前を぀けるこずは必芁ですが。

日付をベヌスにしたバヌゞョニングを䜿っおも、結局マヌゞするタむミングで順番が入れ替わり埌からマヌゞされたマむグレヌションの
バヌゞョンが叀く、゚ラヌになるのではずいう話に぀いおはOut Of Orderで察応するこずもできたす。

環境ごずにディレクトリを分ける

Flywayはクラむアントによりたすが、デフォルトでclasspath:db/migrationJava API、Maven、Gradleの堎合たたは
filesystem:sqlCLIの堎合配䞋にあるマむグレヌションファむルを参照したす。

Locations - Flyway - Product Documentation

これをい぀も適甚するマむグレヌションを含めたディレクトリず、環境別のディレクトリに分けお管理するずよいのかなず思いたす。
たずえばこんな感じですね。

db
└── migration
    ├── common
    │   ├── ....sql
    │   └── ....sql
    ├── development
    │   ├── ....sql
    │   └── ....sql
    ├── production
    │   ├── ....sql
    │   └── ....sql
    └── staging
         ├── ....sql
         └── ....sql

い぀も適甚するマむグレヌションを含んだものをcommonずするず、プロダクション環境向けには以䞋の2぀をマむグレヌションファむルの
配眮先ずしお指定するむメヌゞです。

  • classpath:db/migration/common
  • classpath:db/migration/production

マむグレヌションファむルの眮き堎所は分かれたすが、ディレクトリの内容をたずめお適甚順が決たるのでふ぀うにバヌゞョンを぀けおおけば
OKです。

DDLDCLもずデヌタDMLでディレクトリを分ける

環境別にディレクトリを分けた堎合、マむグレヌションの内容がDDLなのかDMLなのかでディレクトリを分けた方が埌々にわかりやすいのかなず
思いたしお。

むメヌゞ的にはこんな感じです。

└── db
    └── migration
        ├── data
        │   ├── common
        │   │   ├── ....sql
        │   │   └── ....sql
        │   ├── development
        │   │   ├── ....sql
        │   │   └── ....sql
        │   ├── production
        │   │   ├── ....sql
        │   │   └── ....sql
        │   └── staging
        │        ├── ....sql
        │        └── ....sql
        └── ddl
            ├── common
            │   ├── ....sql
            │   └── ....sql
            ├── development
            │   ├── ....sql
            │   └── ....sql
            ├── production
            │   ├── ....sql
            │   └── ....sql
            └── staging
                 ├── xxx.sql
                 └── xxx.sql

DDLがあたり環境別に倉わるこずはないような気はしたすが、DCLDDLではないですがのようなケヌスを考えるず分けおおいた方が
いいのかもしれない、くらいです。 DMLはdataに眮きたす。こちらは登録するデヌタなどになるので、環境別に分けたくなるず思いたす。

䜿い方は環境別にディレクトリを分けた堎合の拡匵のようなものなので、プロダクション環境向けの堎合は以䞋の4぀を
マむグレヌションファむルの配眮先ずしお指定するむメヌゞです。

  • classpath:db/migration/ddl/common
  • classpath:db/migration/ddl/production
  • classpath:db/migration/data/common
  • classpath:db/migration/data/production

DDLは党環境で同じなら、こういうのでもいいかもですね。

└── db
    └── migration
        ├── data
        │   ├── common
        │   │   ├── ....sql
        │   │   └── ....sql
        │   ├── development
        │   │   ├── ....sql
        │   │   └── ....sql
        │   ├── production
        │   │   ├── ....sql
        │   │   └── ....sql
        │   └── staging
        │        ├── ....sql
        │        └── ....sql
        └── ddl
             ├── ....sql
             └── ....sql

指定はこちら。

  • classpath:db/migration/ddl
  • classpath:db/migration/data/common
  • classpath:db/migration/data/production

プロダクション甚のデヌタはGitリポゞトリヌ偎には含めたくないずいう堎合は、実行時にマりントする前提にしおそのディレクトリを指定、
でしょうか。

気になるならOut Of Orderを蚱可する

バヌゞョンの時に少し觊れたしたが、Flywayはマむグレヌションを適甚した埌に最新のバヌゞョンよりも叀いバヌゞョンのマむグレヌション
ファむルを远加するずデフォルトでぱラヌになりたす。

これはチヌム開発をしおいる時に、マむグレヌションを含む修正をマヌゞする順番が入れ替わったりした時などに発生したす。

たずえば20240820日付のマむグレヌションファむルを含む修正ず、20240821日付のマむグレヌションファむルを含む修正を䞊行しお
行っおいたずしたす。この時、バヌゞョンが新しい20240821日付のマむグレヌションが先にマヌゞ・適甚されおしたうず、埌から取り蟌たれた
20240820日付のマむグレヌションは適甚時に゚ラヌになりたす。

この挙動を倉曎するのがOut Of Orderです。

Out Of Order - Flyway - Product Documentation

䞊行しお開発しおいる時のマむグレヌションの内容に䟝存関係がないこずが前提ですが、Out Of Orderをtrueにするず叀いバヌゞョンの
マむグレヌションが远加されおも適甚しおくれたす。

ずいうわけで

ここたでいろいろ䞊べおみたしたが、簡単にサンプルを䜜っおおこうず思いたす。

サンプルはSpring Bootで䜜るこずにしお、マむグレヌションファむルの眮き堎所はこの構造にするこずにしたす。

└── src
    └── main
        └── resources
            └── db
                └── migration
                    ├── data
                    │   ├── common
                    │   │   ├── ....sql
                    │   │   └── ....sql
                    │   ├── development
                    │   │   ├── ....sql
                    │   │   └── ....sql
                    │   ├── production
                    │   │   ├── ....sql
                    │   │   └── ....sql
                    │   └── staging
                    │        ├── ....sql
                    │        └── ....sql
                    └── ddl
                        ├── ....sql
                        └── ....sql

環境

今回の環境はこちら。

$ java --version
openjdk 21.0.4 2024-07-16
OpenJDK Runtime Environment (build 21.0.4+7-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 21.0.4+7-Ubuntu-1ubuntu222.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 21.0.4, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-119-generic", arch: "amd64", family: "unix"

デヌベヌスにはMySQLを䜿甚したす。MySQLサヌバヌは172.17.0.2で動䜜しおいるものずしたす。

 MySQL  localhost:3306 ssl  practice  SQL > select version();
+-----------+
| version() |
+-----------+
| 8.4.2     |
+-----------+
1 row in set (0.0003 sec)

耇数環境を扱うサンプルも䜜ろうず思うのですが、これに぀いおは耇数のデヌタベヌスたでは甚意せず、テヌブルをdropしお環境を
リセットしながら詊しおいこうず思いたす。

Spring Bootプロゞェクトを䜜成する

それでは、Flywayを䜿うSpring Bootプロゞェクトを䜜成したす。

Flywayが実行できればよいので、䟝存関係にはjdbcずflyway、mysqlを含めたす。

$ curl -s https://start.spring.io/starter.tgz \
  -d bootVersion=3.3.3 \
  -d javaVersion=21 \
  -d type=maven-project \
  -d name=flyway-migrations \
  -d groupId=org.littlewings \
  -d artifactId=flyway-migrations \
  -d version=0.0.1-SNAPSHOT \
  -d packageName=org.littlewings.spring.flyway \
  -d dependencies=jdbc,flyway,mysql \
  -d baseDir=flyway-migrations | tar zxvf -

生成されたプロゞェクト内に移動。

$ cd flyway-migrations

䟝存関係などはこのようになっおいたす。

        <properties>
                <java.version>21</java.version>
        </properties>
        <dependencies>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-jdbc</artifactId>
                </dependency>
                <dependency>
                        <groupId>org.flywaydb</groupId>
                        <artifactId>flyway-core</artifactId>
                </dependency>
                <dependency>
                        <groupId>org.flywaydb</groupId>
                        <artifactId>flyway-mysql</artifactId>
                </dependency>

                <dependency>
                        <groupId>com.mysql</groupId>
                        <artifactId>mysql-connector-j</artifactId>
                        <scope>runtime</scope>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                </dependency>
        </dependencies>

        <build>
                <plugins>
                        <plugin>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-maven-plugin</artifactId>
                        </plugin>
                </plugins>
        </build>

生成されたディレクトリおよびファむル。Flyway甚のディレクトリが最初からありたすね。

$ tree -a
.
├── .gitignore
├── .mvn
│   └── wrapper
│       └── maven-wrapper.properties
├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── org
    │   │       └── littlewings
    │   │           └── spring
    │   │               └── flyway
    │   │                   └── FlywayMigrationsApplication.java
    │   └── resources
    │       ├── application.properties
    │       └── db
    │           └── migration
    └── test
        └── java
            └── org
                └── littlewings
                    └── spring
                        └── flyway
                            └── FlywayMigrationsApplicationTests.java

18 directories, 9 files

自動生成されたJavaの゜ヌスコヌドは削陀しおおきたす。

$ rm src/main/java/org/littlewings/spring/flyway/FlywayMigrationsApplication.java src/test/java/org/littlewings/spring/flyway/FlywayMigrationsApplicationTests.java

mainメ゜ッドを持ったクラスの䜜成。

src/main/java/org/littlewings/spring/flyway/App.java

package org.littlewings.spring.flyway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }
}

application.propertiesには、ひずたずデヌタベヌス接続に関する情報を定矩しおおきたす。

src/main/resources/application.properties

spring.application.name=flyway-migrations

spring.datasource.url=jdbc:mysql://172.17.0.2:3306/practice?characterEncoding=utf-8&connectionCollation=utf8mb4_0900_bin
spring.datasource.username=kazuhira
spring.datasource.password=password

Flywayの蚭定ずマむグレヌションの䜜成

では、Flywayに関する蚭定ずマむグレヌションの䜜成を行っおいきたしょう。

たずはディレクトリの䜜成。

$ mkdir src/main/resources/db/migration/{ddl,data}
$ mkdir src/main/resources/db/migration/data/{common,development,production}

環境数は2぀にしおおきたしょう。

たずはこう甚意したした。

$ tree src/main/resources/db/migration
src/main/resources/db/migration
├── data
│   ├── common
│   │   └── V20240825.150000__add_people_data.sql
│   ├── development
│   │   └── V20240825.180000__add_people_data.sql
│   └── production
│       └── V20240825.210000__add_people_data.sql
└── ddl
    ├── V20240825.120000__create_person_table.sql
    └── V20240827.150000__create_book_table.sql

5 directories, 5 files

DDLは人ず曞籍。

src/main/resources/db/migration/ddl/V20240825.120000__create_person_table.sql

create table person(
  id int,
  last_name varchar(20),
  first_name varchar(20),
  age int
  primary key(id)
);

src/main/resources/db/migration/ddl/V20240827.150000__create_book_table.sql

create table book (
  isbn varchar(14),
  title varchar(200),
  price int,
  primary key(isbn)
);

バヌゞョンは少し飛ばしおありたす。

デヌタは、共通に磯野家の人たち芪陀く。

src/main/resources/db/migration/data/common/V20240825.150000__add_people_data.sql

insert into person(id, last_name, first_name, age)
values(1, 'フグ田', 'サザ゚', 24);
insert into person(id, last_name, first_name, age)
values(2, 'フグ田', 'マスオ', 28);
insert into person(id, last_name, first_name, age)
values(3, '磯野', 'カツオ', 11);
insert into person(id, last_name, first_name, age)
values(4, '磯野', 'ワカメ', 9);
insert into person(id, last_name, first_name, age)
values(5, 'フグ田', 'タラオ', 3);

developmentに波野家。

src/main/resources/db/migration/data/development/V20240825.180000__add_people_data.sql

insert into person(id, last_name, first_name, age)
values(6, '波野', 'ノリスケ', 24);
insert into person(id, last_name, first_name, age)
values(7, '波野', 'タむコ', 22);
insert into person(id, last_name, first_name, age)
values(8, '波野', 'むクラ', 1);

productionだず磯野家が党員揃いたす。

src/main/resources/db/migration/data/production/V20240825.210000__add_people_data.sql

insert into person(id, last_name, first_name, age)
values(6, '磯野', '波平', 54);
insert into person(id, last_name, first_name, age)
values(7, '磯野', 'フネ', 50);

デヌタの良し悪しに぀いおは眮いおおきたす 。

これに合わせお、Flywayの蚭定を行いたす。

Common Application Properties / Data Migration Properties

こんな感じになりたした。

src/main/resources/application.properties

spring.application.name=flyway-migrations

spring.datasource.url=jdbc:mysql://172.17.0.2:3306/practice?characterEncoding=utf-8&connectionCollation=utf8mb4_0900_bin
spring.datasource.username=kazuhira
spring.datasource.password=password

## Flyway
spring.flyway.fail-on-missing-locations=true
### マむグレヌションの配眮先
spring.flyway.locations=classpath:db/migration/ddl,classpath:db/migration/data/common,classpath:db/migration/data/development
### Out Of Order
spring.flyway.out-of-order=false
### マむグレヌションの呜名芏則の確認
spring.flyway.validate-migration-naming=true

ひずたずポむントはここだけですね。

### マむグレヌションの配眮先
spring.flyway.locations=classpath:db/migration/ddl,classpath:db/migration/data/common,classpath:db/migration/data/development

以䞋の3぀をマむグレヌションの配眮先に指定しおいたす。

  • classpath:db/migration/ddl
  • classpath:db/migration/data/common
  • classpath:db/migration/data/development

では、パッケヌゞングしお実行。

$ mvn package
$ java -jar target/flyway-migrations-0.0.1-SNAPSHOT.jar

Flywayが実行されたした。

2024-08-28T15:45:12.997+09:00  INFO 26843 --- [flyway-migrations] [           main] org.flywaydb.core.FlywayExecutor         : Database: jdbc:mysql://172.17.0.2:3306/practice (MySQL 8.4)
2024-08-28T15:45:13.145+09:00  WARN 26843 --- [flyway-migrations] [           main] o.f.c.internal.database.base.Database    : Flyway upgrade recommended: MySQL 8.4 is newer than this version of Flyway and support has not been tested. The latest supported version of MySQL is 8.1.
2024-08-28T15:45:13.199+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Schema history table `practice`.`flyway_schema_history` does not exist yet
2024-08-28T15:45:13.206+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.core.internal.command.DbValidate     : Successfully validated 4 migrations (execution time 00:00.044s)
2024-08-28T15:45:13.265+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table `practice`.`flyway_schema_history` ...
2024-08-28T15:45:13.540+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `practice`: << Empty Schema >>
2024-08-28T15:45:13.552+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240825.120000 - create person table"
2024-08-28T15:45:13.738+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240825.150000 - add people data"
2024-08-28T15:45:13.812+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240825.180000 - add people data"
2024-08-28T15:45:13.855+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240827.150000 - create book table"
2024-08-28T15:45:14.012+09:00  INFO 26843 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 4 migrations to schema `practice`, now at version v20240827.150000 (execution time 00:00.254s)

テヌブルの状態を確認しおみたす。

 MySQL  localhost:3306 ssl  practice  SQL > show tables;
+-----------------------+
| Tables_in_practice    |
+-----------------------+
| book                  |
| flyway_schema_history |
| person                |
+-----------------------+
3 rows in set (0.0014 sec)

適甚されたマむグレヌションの䞀芧。

 MySQL  localhost:3306 ssl  practice  SQL > select * from flyway_schema_history;
+----------------+-----------------+---------------------+------+-------------------------------------------+------------+--------------+---------------------+----------------+---------+
| installed_rank | version         | description         | type | script                                    | checksum   | installed_by | installed_on        | execution_time | success |
+----------------+-----------------+---------------------+------+-------------------------------------------+------------+--------------+---------------------+----------------+---------+
|              1 | 20240825.120000 | create person table | SQL  | V20240825.120000__create_person_table.sql | -123870336 | kazuhira     | 2024-08-28 06:45:13 |            114 |       1 |
|              2 | 20240825.150000 | add people data     | SQL  | V20240825.150000__add_people_data.sql     | -181951584 | kazuhira     | 2024-08-28 06:45:13 |             11 |       1 |
|              3 | 20240825.180000 | add people data     | SQL  | V20240825.180000__add_people_data.sql     | -745607530 | kazuhira     | 2024-08-28 06:45:13 |             32 |       1 |
|              4 | 20240827.150000 | create book table   | SQL  | V20240827.150000__create_book_table.sql   | 1689297802 | kazuhira     | 2024-08-28 06:45:13 |             97 |       1 |
+----------------+-----------------+---------------------+------+-------------------------------------------+------------+--------------+---------------------+----------------+---------+
4 rows in set (0.0005 sec)

DDLずcommonずdevelopmentのデヌタのみが適甚されおいるはずです。

デヌタで確認しおみたしょう。

 MySQL  localhost:3306 ssl  practice  SQL > select * from person;
+----+-----------+------------+-----+
| id | last_name | first_name | age |
+----+-----------+------------+-----+
|  1 | フグ田    | サザ゚     |  24 |
|  2 | フグ田    | マスオ     |  28 |
|  3 | 磯野      | カツオ     |  11 |
|  4 | 磯野      | ワカメ     |   9 |
|  5 | フグ田    | タラオ     |   3 |
|  6 | 波野      | ノリスケ   |  24 |
|  7 | 波野      | タむコ     |  22 |
|  8 | 波野      | むクラ     |   1 |
+----+-----------+------------+-----+
8 rows in set (0.0005 sec)

OKですね。

もうひず぀の方にはデヌタは入れおいたせん。

 MySQL  localhost:3306 ssl  practice  SQL > select * from book;
Empty set (0.0010 sec)

ここで、すべおのテヌブルをdropしたす。

 MySQL  localhost:3306 ssl  practice  SQL > drop table flyway_schema_history;drop table person;drop table book;

マむグレヌションの配眮先を、環境倉数で切り替えおみたしょう。

$ export SPRING_FLYWAY_LOCATIONS=classpath:db/migration/ddl,classpath:db/migration/data/common,classpath:db/migration/data/production

぀たり、マむグレヌションの配眮先はこうなっおいたす。

  • classpath:db/migration/ddl
  • classpath:db/migration/data/common
  • classpath:db/migration/data/production

developmentがproductionに倉わったわけですね。

実行したす。

$ java -jar target/flyway-migrations-0.0.1-SNAPSHOT.jar

実行時のログ。

2024-08-28T15:49:09.550+09:00  INFO 27033 --- [flyway-migrations] [           main] org.flywaydb.core.FlywayExecutor         : Database: jdbc:mysql://172.17.0.2:3306/practice (MySQL 8.4)
2024-08-28T15:49:09.653+09:00  WARN 27033 --- [flyway-migrations] [           main] o.f.c.internal.database.base.Database    : Flyway upgrade recommended: MySQL 8.4 is newer than this version of Flyway and support has not been tested. The latest supported version of MySQL is 8.1.
2024-08-28T15:49:09.696+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Schema history table `practice`.`flyway_schema_history` does not exist yet
2024-08-28T15:49:09.702+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.core.internal.command.DbValidate     : Successfully validated 4 migrations (execution time 00:00.032s)
2024-08-28T15:49:09.731+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table `practice`.`flyway_schema_history` ...
2024-08-28T15:49:10.004+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `practice`: << Empty Schema >>
2024-08-28T15:49:10.018+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240825.120000 - create person table"
2024-08-28T15:49:10.173+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240825.150000 - add people data"
2024-08-28T15:49:10.224+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240825.210000 - add people data"
2024-08-28T15:49:10.341+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240827.150000 - create book table"
2024-08-28T15:49:10.542+09:00  INFO 27033 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 4 migrations to schema `practice`, now at version v20240827.150000 (execution time 00:00.253s)

適甚されたマむグレヌションの䞀芧。

 MySQL  localhost:3306 ssl  practice  SQL > select * from flyway_schema_history;
+----------------+-----------------+---------------------+------+-------------------------------------------+-------------+--------------+---------------------+----------------+---------+
| installed_rank | version         | description         | type | script                                    | checksum    | installed_by | installed_on        | execution_time | success |
+----------------+-----------------+---------------------+------+-------------------------------------------+-------------+--------------+---------------------+----------------+---------+
|              1 | 20240825.120000 | create person table | SQL  | V20240825.120000__create_person_table.sql |  -123870336 | kazuhira     | 2024-08-28 06:49:10 |            106 |       1 |
|              2 | 20240825.150000 | add people data     | SQL  | V20240825.150000__add_people_data.sql     |  -181951584 | kazuhira     | 2024-08-28 06:49:10 |             11 |       1 |
|              3 | 20240825.210000 | add people data     | SQL  | V20240825.210000__add_people_data.sql     | -1450894877 | kazuhira     | 2024-08-28 06:49:10 |              7 |       1 |
|              4 | 20240827.150000 | create book table   | SQL  | V20240827.150000__create_book_table.sql   |  1689297802 | kazuhira     | 2024-08-28 06:49:10 |            129 |       1 |
+----------------+-----------------+---------------------+------+-------------------------------------------+-------------+--------------+---------------------+----------------+---------+
4 rows in set (0.0005 sec)

デヌタを確認しおみたす。

 MySQL  localhost:3306 ssl  practice  SQL > select * from person;
+----+-----------+------------+-----+
| id | last_name | first_name | age |
+----+-----------+------------+-----+
|  1 | フグ田    | サザ゚     |  24 |
|  2 | フグ田    | マスオ     |  28 |
|  3 | 磯野      | カツオ     |  11 |
|  4 | 磯野      | ワカメ     |   9 |
|  5 | フグ田    | タラオ     |   3 |
|  6 | 磯野      | 波平       |  54 |
|  7 | 磯野      | フネ       |  50 |
+----+-----------+------------+-----+
7 rows in set (0.0004 sec)

development甚のデヌタはなくなり、productionのデヌタが远加されたした。

OKですね。

ずころで、よく芋るずFlywayはMySQL 8.4をただサポヌトしおいないみたいですね 。

2024-08-28T15:45:13.145+09:00  WARN 26843 --- [flyway-migrations] [           main] o.f.c.internal.database.base.Database    : Flyway upgrade recommended: MySQL 8.4 is newer than this version of Flyway and support has not been tested. The latest supported version of MySQL is 8.1.

確認時点だず、確かにそうでした。

Verified Versions: 5.7, 8.0, 8.1

MySQL - Flyway - Product Documentation

Out Of Orderを詊す

最埌にOut Of Orderを詊しおみたしょう。

マむグレヌションは、developmentで適甚枈みずしたす。

぀たり、この状態ですね。

 MySQL  localhost:3306 ssl  practice  SQL > select * from flyway_schema_history;
+----------------+-----------------+---------------------+------+-------------------------------------------+------------+--------------+---------------------+----------------+---------+
| installed_rank | version         | description         | type | script                                    | checksum   | installed_by | installed_on        | execution_time | success |
+----------------+-----------------+---------------------+------+-------------------------------------------+------------+--------------+---------------------+----------------+---------+
|              1 | 20240825.120000 | create person table | SQL  | V20240825.120000__create_person_table.sql | -123870336 | kazuhira     | 2024-08-28 06:53:31 |            112 |       1 |
|              2 | 20240825.150000 | add people data     | SQL  | V20240825.150000__add_people_data.sql     | -181951584 | kazuhira     | 2024-08-28 06:53:31 |              9 |       1 |
|              3 | 20240825.180000 | add people data     | SQL  | V20240825.180000__add_people_data.sql     | -745607530 | kazuhira     | 2024-08-28 06:53:31 |              6 |       1 |
|              4 | 20240827.150000 | create book table   | SQL  | V20240827.150000__create_book_table.sql   | 1689297802 | kazuhira     | 2024-08-28 06:53:31 |             82 |       1 |
+----------------+-----------------+---------------------+------+-------------------------------------------+------------+--------------+---------------------+----------------+---------+
4 rows in set (0.0004 sec)


 MySQL  localhost:3306 ssl  practice  SQL > select * from person;
+----+-----------+------------+-----+
| id | last_name | first_name | age |
+----+-----------+------------+-----+
|  1 | フグ田    | サザ゚     |  24 |
|  2 | フグ田    | マスオ     |  28 |
|  3 | 磯野      | カツオ     |  11 |
|  4 | 磯野      | ワカメ     |   9 |
|  5 | フグ田    | タラオ     |   3 |
|  6 | 波野      | ノリスケ   |  24 |
|  7 | 波野      | タむコ     |  22 |
|  8 | 波野      | むクラ     |   1 |
+----+-----------+------------+-----+
8 rows in set (0.0005 sec)

ここで最埌のマむグレヌションファむルの日付は20240827でしたが、20240826のものを割り蟌たせおみたす。

src/main/resources/db/migration/ddl/V20240826.180000__create_category_table.sql

create table category (
  id varchar(3),
  name varchar(20),
  primary key(id)
);

パッケヌゞングしお実行。

$ mvn package
$ java -jar target/flyway-migrations-0.0.1-SNAPSHOT.jar

するず、未適甚のマむグレヌションが怜出されたずいうこずで倱敗したす。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Validate failed: Migrations have failed validation
Detected resolved migration not applied to database: 20240826.180000.
To ignore this migration, set -ignoreMigrationPatterns='*:ignored'. To allow executing this migration, set -outOfOrder=true.
Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1806) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971) ~[spring-context-6.1.12.jar!/:6.1.12]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.12.jar!/:6.1.12]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.3.jar!/:3.3.3]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.3.jar!/:3.3.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.3.jar!/:3.3.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.3.jar!/:3.3.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.3.jar!/:3.3.3]
        at org.littlewings.spring.flyway.App.main(App.java:9) ~[!/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:102) ~[flyway-migrations-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64) ~[flyway-migrations-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40) ~[flyway-migrations-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
Detected resolved migration not applied to database: 20240826.180000.
To ignore this migration, set -ignoreMigrationPatterns='*:ignored'. To allow executing this migration, set -outOfOrder=true.
Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE
        at org.flywaydb.core.Flyway.lambda$migrate$0(Flyway.java:160) ~[flyway-core-10.10.0.jar!/:na]
        at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:205) ~[flyway-core-10.10.0.jar!/:na]
        at org.flywaydb.core.Flyway.migrate(Flyway.java:147) ~[flyway-core-10.10.0.jar!/:na]
        at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) ~[spring-boot-autoconfigure-3.3.3.jar!/:3.3.3]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-6.1.12.jar!/:6.1.12]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1802) ~[spring-beans-6.1.12.jar!/:6.1.12]
        ... 22 common frames omitted

この郚分ですね。

Validate failed: Migrations have failed validation
Detected resolved migration not applied to database: 20240826.180000.

これをそのたた適甚しおもいいよずいう堎合は、メッセヌゞに曞かれおいるように無芖するかOut Of Orderをtrueにしたす。

To ignore this migration, set -ignoreMigrationPatterns='*:ignored'. To allow executing this migration, set -outOfOrder=true.

今回はOut Of Orderをtrueにしたしょう。application.propertiesをこう倉曎したす。

### Out Of Order
spring.flyway.out-of-order=true

環境倉数で指定したりしお、䞀時的に切り替えおもよいでしょう。

$ export SPRING_FLYWAY_OUTOFORDER=true

application.propertiesを倉曎した堎合は、パッケヌゞングしお実行。

$ mvn package
$ java -jar target/flyway-migrations-0.0.1-SNAPSHOT.jar

「outOfOrder mode is active.」ず衚瀺され、マむグレヌションを適甚しおくれたす。

2024-08-28T15:59:20.540+09:00  INFO 27655 --- [flyway-migrations] [           main] org.flywaydb.core.FlywayExecutor         : Database: jdbc:mysql://172.17.0.2:3306/practice (MySQL 8.4)
2024-08-28T15:59:20.633+09:00  WARN 27655 --- [flyway-migrations] [           main] o.f.c.internal.database.base.Database    : Flyway upgrade recommended: MySQL 8.4 is newer than this version of Flyway and support has not been tested. The latest supported version of MySQL is 8.1.
2024-08-28T15:59:20.682+09:00  INFO 27655 --- [flyway-migrations] [           main] o.f.core.internal.command.DbValidate     : Successfully validated 5 migrations (execution time 00:00.037s)
2024-08-28T15:59:20.702+09:00  INFO 27655 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `practice`: 20240827.150000
2024-08-28T15:59:20.702+09:00  WARN 27655 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : outOfOrder mode is active. Migration of schema `practice` may not be reproducible.
2024-08-28T15:59:20.724+09:00  INFO 27655 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `practice` to version "20240826.180000 - create category table" [out of order]
2024-08-28T15:59:21.088+09:00  INFO 27655 --- [flyway-migrations] [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 1 migration to schema `practice`, now at version v20240826.180000 (execution time 00:00.219s)

確認しおみたしょう。

 MySQL  localhost:3306 ssl  practice  SQL > show tables;
+-----------------------+
| Tables_in_practice    |
+-----------------------+
| book                  |
| category              |
| flyway_schema_history |
| person                |
+-----------------------+
4 rows in set (0.0013 sec)

テヌブルはできおいたす。

適甚されたマむグレヌションの䞀芧。

 MySQL  localhost:3306 ssl  practice  SQL > select * from flyway_schema_history;
+----------------+-----------------+-----------------------+------+---------------------------------------------+------------+--------------+---------------------+----------------+---------+
| installed_rank | version         | description           | type | script                                      | checksum   | installed_by | installed_on        | execution_time | success |
+----------------+-----------------+-----------------------+------+---------------------------------------------+------------+--------------+---------------------+----------------+---------+
|              1 | 20240825.120000 | create person table   | SQL  | V20240825.120000__create_person_table.sql   | -123870336 | kazuhira     | 2024-08-28 06:53:31 |            112 |       1 |
|              2 | 20240825.150000 | add people data       | SQL  | V20240825.150000__add_people_data.sql       | -181951584 | kazuhira     | 2024-08-28 06:53:31 |              9 |       1 |
|              3 | 20240825.180000 | add people data       | SQL  | V20240825.180000__add_people_data.sql       | -745607530 | kazuhira     | 2024-08-28 06:53:31 |              6 |       1 |
|              4 | 20240827.150000 | create book table     | SQL  | V20240827.150000__create_book_table.sql     | 1689297802 | kazuhira     | 2024-08-28 06:53:31 |             82 |       1 |
|              5 | 20240826.180000 | create category table | SQL  | V20240826.180000__create_category_table.sql | 1347572117 | kazuhira     | 2024-08-28 06:59:20 |            219 |       1 |
+----------------+-----------------+-----------------------+------+---------------------------------------------+------------+--------------+---------------------+----------------+---------+
5 rows in set (0.0005 sec)

叀い日付のマむグレヌションのinstalled_rankが最新になっおいるものの、適甚されおいるようです。

テヌブルにもアクセスできたす。

 MySQL  localhost:3306 ssl  practice  SQL > select * from category;
Empty set (0.0018 sec)

ずいうわけで、Out Of Orderの効果を確認できたした。

おわりに

Flywayのマむグレヌションの管理ずいうこずで、バヌゞョンの付け方やマむグレヌションの配眮先などをいろいろ曞いおみたした。
このやり方で埮劙に思うずころはあったりもするのですが、いろいろ考えおこの付近が劥協点かなずも思ったり。

参考になればずいうこずもありたすが、自分はこのあたりをベヌスに考えたいず思いたす。