FlywayでValidate failed: Detected resolved migration not applied to databaseが発生するときの対処法

Dec 5, 2017 ( Feb 11, 2022 更新 )

マージタイミングによって適応されるmigrationが想定外になる場合

flywayはクラスパス上にあるSQLファイル名のversion, descriptionの順にJavaのマイグレーションクラス、SQLを実行する。 また、適応したmigarationの情報はschema_versionテーブルに保存される。

並行開発していると、各々が想定していたバージョンをつけている場合マージ時にコンフリクトする。

コンフリクト解消が面倒だったため、あらかじめバージョン番号を宣言しておいてからマイグレーションファイルを作るという運用1にしていたが、そうすると以下のようにバージョンの歯抜けが発生してしまうということがあった。

|             26 | 1.1.24  | AddExternalMessages                                            | SQL  | V1.1.24__AddExternalMessages.sql                                           | -1267961536 | app      | 2017-11-29 12:07:06 |            263 |       1 |
|             27 | 1.1.26  | UpdateCustomerPoilicies                                        | SQL  | V1.1.26__UpdateCustomerPoilicies.sql                                       |  2084759646 | app      | 2017-12-04 11:25:21 |             32 |       1 |
+----------------+---------+----------------------------------------------------------------+------+----------------------------------------------------------------------------+-------------+--------------+---------------------+----------------+---------+

この状態で1.1.25のmigrationを適用しようとすると Validate failed: Detected resolved migration not applied to database が発生してしまいmigration実行できない。

schema_versionの修正

|             26 | 1.1.24  | AddExternalMessages                                            | SQL  | V1.1.24__AddExternalMessages.sql                                           | -1267961536 | app      | 2017-11-29 12:07:06 |            263 |       1 |
|             27 | 1.1.26  | UpdateCustomerPoilicies                                        | SQL  | V1.1.26__UpdateCustomerPoilicies.sql                                       |  2084759646 | app      | 2017-12-04 11:25:21 |             32 |       1 |
+----------------+---------+----------------------------------------------------------------+------+----------------------------------------------------------------------------+-------------+--------------+---------------------+----------------+---------+

この場合installed_rank=27にversion1.1.25を差し込みたいので、以下のように手でschema_versionテーブルのinstalled_rankを変更し、いれたいversionのメタ情報をinsertする。

mysql> update schema_version set installed_rank=28 where version = '1.1.26';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> insert into schema_version(installed_rank, version, description, type, script, checksum, installed_by, installed_on, execution_time, success) values(27, '1.1.25', 'ChangeSomething', 'SQL', 'V1.1.25__ChangeSomething.sql', 855077581, 'root', '2017-12-04 11:00:19', 1, 1);
Query OK, 1 row affected (0.03 sec)

flyway migrateで入らなかったデータの投入

メタデータのテーブルを更新したら、入れたかったデータを手動投入したり更新したりする。

こういう運用にしないようにしたい

バージョンのことを考えなくてもよいように、

  • プログラマは自分の変更に関するmigrationを書く。リポジトリにコミットする
  • ジョブでmigrationを実行する前に、migration sqlにバージョン番号をふってコミットする
  • flyway migrate実行

のような感じにしたい。

それか、そもそも開発中のDBにはcleanしてmigarateしてもいいような仕切りにしたい。 自分が投入したデータがテストで必要、とかないようにしたい…。


  1. 本質的にはこういう運用もやめたい。バージョンがコンフリクトしたときに直すほうがまだマシな気がしてきた ↩︎

Return to top