flywayとは?
DBのスキーマ変更をバージョン管理するツール。
DDLとDML呼ばれるSQLファイルを作成し、コマンドラインでMigrationすることでDBを変更する。
DDL
Data Definition Language。スキーマの定義や変更(CREATE、ALTER、DROP、TRUNCATE)を管理する。バージョンをインクリメントして整合性を保つ。
DML
Data Manipulation Language。マスタデータを更新(INSERT、UPDATE、DELETE、SELECT)する。バージョン管理はしない。
機能
指定変数の使用
DDL、DML内で変数を使用したい場合、placeholders機能を使用する。
build.gradle に以下のように記述する。
flyway {
placeholders = [
'apl': 'APL_PROD',
'host': 'HST_PROD'
]
}
上記の例で、DDL内で${val1}と記述すると、APL_PRODが代入される。
Appendix
flyway_schema_historyはどこに配置するべき?
flyway_schema_historyテーブルは管理者にしか見えないようにするべきか、それなら別のスキーマにするべきか、など迷うことがあると思う。
基本的には自分のスキーマに作成し、アプリ用ユーザーで管理するのがベストプラクティス。
特に保守では、リリース日の異なる複数案件を同時開発するので、DDLの順序が途中で変わったりするケースもよくある。
そのときに、flyway_schema_historyを、管理者ではなく開発者レベルで修正することがあるため。
僕のプロジェクトは少し特殊で、CI/CDにJenkinsを使用し、管理者ユーザーによって複数環境をデプロイさせる必要があったため、各環境それぞれ、flyway_schema_historyを管理するためだけのスキーマを用意し、管理者は横ぐしでアクセスできるような構成を取っていた。
flyway_schema_history がどこにあるか調べる
SELECT owner, table_name
FROM all_tables
WHERE table_name LIKE 'flyway_%';
インシデント
Detected resolved migration not applied to database: XXX
flywayMigrate実行時エラー
> Task : flywayMigrate
Caching disabled for task ':flywayMigrate' because;
Build cache is disabled
Task flywayMigrate' is not up-to-date because:
Task has not declared any outputs despite executing actions.
* What went wrong:
Execution failed for task ': flywayMigrate'.
> Error occurred while executing flywayMigrate
Validate failed:
Detected resolved migration not applied to database: 00.000.563
Detected resolved migration not applied to database: 00.000.564
Detected resolved migration not applied to database: 00.000.565
Detected resolved migration not applied to database: 00.000.566
Detected resolved migration not applied to database: 00.000.567
以下のコマンドを実行して、定義ファイルをチェックする
gradlew flywayValidate
以下の条件でFAILEDとなる。
- 『flyway_schema_history』と『定義ファイル』のtypeとchecksumが不一致
- 『build.gradle の target』と『Schema version』が不一致
>FAILEしたので定義ファイルがおかしい
flywayMigrate実行ログを見てみると、以下のエラー。
Detected resolved migration not applied to database: 00.000.XXX // データベースに適用されていない解決済みの移行が検出されました
flyway Infoで見たところ、実行履歴の一部がIgnoreとなっており、これらが無視されているため順序がおかしいとのエラーが出ているよう。
scheme_historyを修正する_方法1
手順は複雑だが、何が起きているかわかりやすいのでまずはこちらで解説する。
とにかく簡単に解消だけしたい場合は方法2を参照。
flywayのバージョンはscheme_historyというテーブルで管理されているので、このテーブルを修正する。
例えば、バージョン100と200でMigrate済みのスキーマに、バージョン150のDDLを追加してMigrateしようとすると、150がIgnoreとなる。 以下の手順で解消する。
scheme_historyに接続し、バージョン200のレコードを削除する。
flywayMigrate実行すると、バージョン150は通るが、以下のエラーとなる。
ORA-00955: name is already used by an existing object // ORA-00955: すでに使用されているオブジェクト名です
バージョン200はすでに実行済みのため、同じテーブルを作ろうとしてエラーとなっている。
scheme_historyのバージョン200のレコードを見ると、success カラムが0となっているので、これを1に変えてあげる。
scheme_historyを修正する_方法2
flywayInfoで、Ignoreとなっているhistoryレコードを削除(バックアップはしておく)し、flywayMigrateを再実行する。
Migration checksum mismatch for migration version 00.000.XXX
flywayMigrate実行時エラー。
flywayRepairで修復可能。
ORA-01031
新しいスキーマにはじめてflywayMigrateを実行した際のエラー。
CREATE TABLE などの基本的な権限はユーザーに付与してある。
エラーメッセージ
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException:
Unable to create schema "schemaXX"
SQL State: 42000
Error Code: 1031
Message: ORA-01031: 権限が不足しています
~~~ ~~~
at org.flywaydb.core.internal.database.base.Schema.create(Schema.java:118)
... 160 more
Caused by: Error: 1031, Position: 0, Sql = CREATE USER "schemaXX" IDENTIFIED BY OriginalSql = CREATE USER "schemaXX" IDENTIFIED BY "FFllyywwaayyoo!!", Error Msg = ORA-01031: 権限が不足しています
at oracle.jdbc.driver.T4CTTloer11.processError(T4CTTloer11.java:513)
なぜか CREATE USER を使おうとしている、つまりは新しいスキーマを作ろうとしてしまっている。
flywayの設定(build.gradle)で、スキーマ名の指定が間違っている場合、flywayは新規スキーマとして作成しようとするためこのエラーが起こる。
build.gradleのスキーマ指定箇所を見てみると、大文字で記載されるべきスキーマ名が小文字になっていたので、大文字に変更して解消した。
Found non-empty schema(s)
flyway実行前にテーブルにデータ移行したため、 空でないスキーマにflywayは実行でき
ないと怒られている。
すべてのテーブルをDROPして再実行し解消。
ORA-01031: 権限が不足しています
flywayInfoは実行できるが、flywayMigrateを実行しようとするとタイトルのエラーが発生する。
これは、ユーザーにCREATE、ALTER等の実行権限が不足しているために起きる。
『Oracle Database SQL備忘録-権限設定』を参考に、自身のユーザーのロールや権限を確認する。
flyway_schema_history に SQL でアクセスできない
以下のSQLでflyway_schema_historyにアクセスしようとしたが、テーブルが見つからない。
select * from flyway_schema_history;
テーブル名を以下のようにダブルクオーテーションで囲わないと、大文字に変換されてしまい、テーブルを検知できない。
select * from "flyway_schema_history";

コメント