😺

なんとなく使わないFlyway

2022/09/23に公開

動機

Java で DB マイグレーションするんだったら Flyway みたいな感じで何となく使っていたけど、エラーが出たときとかは雰囲気で対処していた。
また Java で書ける性質もあり、誰かがゴリゴリにカスタマイズした Flyway を使っていたりしたので基本動作がよくわからなくなっていた。
そんな中業務でマイグレーションの状態を破壊してしまったりしたので、いい加減ちゃんと知ろうと思って調べてみた。

Flyway とは

Redgate 社が開発しているマイグレーション管理・実行ツール。
フリープランと有料プランがあり、フリープランの実装は GitHub でApache License v2として公開されている。
有料プランになると追加でいろいろなコマンドが使えたり、Redgate 社から直接サポートを受けることができる。
個人的には以下の 3 点が目を引いた。

  • 10 年前にリリースされた DB のリリースのサポート(通常は 5 年以内)
  • Dry-run
  • Undo

他にも様々な機能があるため、詳しくは公式の Download + pricingを参照。

また DB マイグレーションの管理の他に、Preview ではあるがFlyway Hubという GitHub と直接連携して CI 上でマイグレーションの整合性をチェックしてくれる機能があったりする。

基本的な使用方法

特定のディレクトリに特定の命名規則に沿った形で SQL を置いてflyway migrateを実行すると、整合性のチェックが行われた後に問題がなければ SQL が実行される。
整合性のチェックにはflyway_shema_historyというメタテーブルが利用されている。
このテーブルは初めてflyway migrateか、後述するflyway baselineというコマンドを利用したときに作成される。
スキーマは以下のようになっている。

create table flyway_schema_history
(
    installed_rank integer                 not null -- 実行済みSQLの順序
        constraint flyway_schema_history_pk
            primary key,
    version        varchar(50),
    description    varchar(200)            not null,
    type           varchar(20)             not null, -- FlywayはSQL以外でもマイグレーションを実行できるため、どんな形式のマイグレーションが実行されたかが記載されている
    script         varchar(1000)           not null, -- マイグレーションに利用されたファイルのパス.
    checksum       integer,                          -- チェックサム. SQLファイルの整合性チェックに利用される.
    installed_by   varchar(100)            not null,
    installed_on   timestamp default now() not null,
    execution_time integer                 not null,
    success        boolean                 not null -- マイグレーションが成功したかどうか.
);


create index flyway_schema_history_s_idx
    on flyway_schema_history (success);

今回は利用できるコマンドについて詳しく調べてみた。
Flyway には 7 つのコマンドがある。前述の通りundoは有料版限定である。

migrate

利用方法

flyway migrate

実行内容

特定のディレクトリ配下の SQL ファイルを再帰的に探索し、順に SQL が実行される。
通常のマイグレーションの他にリピータブルマイグレーションというマイグレーションが実行される度に SQL が実行される仕組みがある。

デフォルトでは以下の仕様でマイグレーションが行われる。
ちなみにプリフィックス・サフィックス・セパレータはオプションにより変更可能である。
それ以外の文字は何でも良い。

通常のマイグレーション

過去実行された SQL ファイルのチェックサムと、現在のチェックサムを検証した上で、相違がなければ未適用の SQL を実行する。

  • プリフィックス: V
  • セパレータ: __
  • サフィックス: .sql

リピータブルマイグレーション

チェックサムに変更があった場合マイグレーションが実行される。

  • プリフィックス: R
  • セパレータ: __
  • サフィックス: .sql

細かな仕様

プリフィックスとセパレータの間はバージョンとして扱われ、flyway_schema_history.versionに記録されている。
このバージョンはflyway migrate -target=<version>で渡すことで指定したバージョン以降のマイグレーションだけを実行することができる。

clean

スキーマ内のすべてのオブジェクトが削除される

利用方法

flyway clean

info

これまでに行ったマイグレーションとそのステータスを確認できる。
よく目にするステータスはこれら

  • Pending
    • クラスパスに含まれているがflyway_schema_historyに未登録
  • Success
    • クラスパスに含まれており、flyway_schema_historyにレコードが登録済み、かつflyway_schema_history.success=trueの場合
  • Failed
    • 何らかの理由で SQL の適用に失敗している
      • チェックサムの検証でコケている
      • SQL の実行でエラーになる

ステータスの一覧はこちら

利用方法

flyway info

validate

クラスパス内に存在するマイグレーションファイルと、現在の DB にあたっているマイグレーションとのチェックサムを比較し、差異がある場合はエラーを吐く

利用方法

flyway validate

undo

flyway migrateと同じ要領で undo 用のマイグレーションファイルが実行される。
migrate がコケたり間違って当てたりしたときに直してくる魔法のようなコマンドだと思っていたのだが、そんなことはない。
また、リピータブルマイグレーションに対して undo するような SQL を実行することもできない。
以下のルールに沿って作成された SQL が実行される。

  • プリフィックス: U
  • セパレータ: __
  • サフィックス: .sql

利用方法

flyway undo

baseline

baseline は flyway で管理がされていない DB に対して、自分が今どこにいるかを定義するコマンド。

利用方法

flyway baseline -baselineVersion=1.0.0

例えば DB とマイグレーションファイルが以下の状態であるとする

  • マイグレーションファイル
    • V1__foo.sql
    • V2__bar.sql
  • DB A
    • V1 相当の DDL があたっているが、flyway で管理されていない

このときにflyway baseline -baselineVersion=1.1.0を実行すると以下のようになる。

+------------+------------+--------------------------------------------------------------------------------+----------+---------------------+----------+
| Category   | Version    | Description                                                                    | Type     | Installed On        | State    |
+------------+------------+--------------------------------------------------------------------------------+----------+---------------------+----------+
|            | 1.1        | << Flyway Baseline >>                                                          | BASELINE | 2022-08-25 01:34:07 | Baseline |
| Versioned  | 2          | V2__bar                                                                        | SQL      |                     | Pending  |
+------------+------------+--------------------------------------------------------------------------------+----------+---------------------+----------+

repair

flyway infoで ステータスが Failed となるマイグレーションファイルをPendingにする

利用方法

flyway repair

check

レポートを作成してくれるらしい。

Requirements
.NET 6 is required in order to generate reports. You can download it from here.
sqlfluff is required for Code Analysis (-code). You can install it by running pip3 install sqlfluff==1.2.1.

とあり、生成するのは大変である。

利用方法

flyway check

snapshot

DB のスナップショットを取ることができる。
現在は有料版でのみ β 版の提供らしいが、将来的に無償版でも利用できるようになるらしい。

利用方法

flyway snapshot

その他機能

Dry run

flyway migrate を実行すると走る SQL を 1 つのファイルにまとめて出力する機能。
flyway migrate -dryRunOutput=dryrun.sqlとすると、以下のように出力される。
(引用元: https://flywaydb.org/documentation/tutorials/dryruns#doing-a-dry-run)

---====================================
-- Flyway Dry Run (2018-01-25 17:19:17)
---====================================

SET SCHEMA "PUBLIC";

-- Executing: validate (with callbacks)
------------------------------------------------------------------------------------------
-- ...

-- Executing: migrate (with callbacks)
------------------------------------------------------------------------------------------
-- ...

-- Executing: migrate -> v3 (with callbacks)
------------------------------------------------------------------------------------------

-- Source: ./V3__Couple.sql
---------------------------
create table COUPLE (
    ID int not null,
    PERSON1 int not null references PERSON(ID),
    PERSON2 int not null references PERSON(ID)
);
INSERT INTO "PUBLIC"."flyway_schema_history" ("installed_rank","version","description","type","script","checksum","installed_by","execution_time","success") VALUES (2, '3', 'Couple', 'SQL', 'V3__Couple.sql', -722651034, 'SA', 0, 1);
-- ...

Flyway Hub

公式によると以下のことが可能

  • マイグレーションファイルの構文チェック
  • マイグレションファイルの実行順序のチェック
  • バージョン番号のコンフリクトの検知
  • GitHub で管理しているマイグレーションファイルから新しい環境を作る

これは必要なのか・・・?

Flyway Hub 公式サイト: https://flywaydb.org/documentation/hub/overview.html

参考資料

GitHubで編集を提案

Discussion