NHN Cloud Meetup 編集部
DBも構成管理をしてみよう!
2018.12.11
5,480
開発コードはVCS(Version Control System)で構成管理をしているのに、DBの変更履歴も構成管理ができないか、と悩まれたことはありませんか?
DBの変更履歴も構成管理できるオープンソースのツールFlywayを紹介します。バージョン別DBスクリプトファイルは、おそらく次のようにスクリプトファイルをずーっと列挙して管理し、いちいちファイルをDBMSで実行していたのではないでしょうか。
もちろん、スクリプトファイルをVCSに構成管理をしてもよいですが、ともすればHuman Faultが発生することがあります。アプリケーションはバージョンアップしたのに、変更されたDBのスクリプトが実行されない場合、障害にもつながりかねません。
バージョン別スキーマの変更管理は?アプリケーション駆動のプロビジョニングデータ管理は?いちいち直接記憶して実行してくれるでしょうか?
ここにHuman Faultを削減することができるFlywayオープンソースDBの構成管理ツールがあります。ローカル、検証環境などの開発DBで変更したSchema、Index、Keyなどステージング環境、運営DBで漏れる部分をFlywayを使用して防ぐことができます。また単体テストでもIn-Memory DB(H2、derby、Hsqldbなど)にDB DDL履歴を実行して、リモートと同じようなDBの形状を維持したまま、単体テストを行うことができます。
すなわち、DBサーバーが連動しなくても単位テストは成功してこそ真のテストコードと言えます。
Flywayはこれを可能にするツールです。
Flywayを開始する
まず、上記ファイルをV + バージョン + __ + 説明.sql規則でファイル名を作成します。V1.0__INIT.sqlのように。それではFlyway Pluginがflyway_schema_history内部スキーマを使用してファイルのバージョンを管理します。
下図のようにShiny DB version 2でversion 2.1にバージョンが上方修正され、2つのTABLEが削除された場合には、V2.1__refactoring.sqlファイルにDROP TABLE ..を記述します。
Flyway Pluginは、内部スキーマの登録情報に基づいてバージョン順にファイル内容を実行します。
例えば、version 2は既に登録された情報であり、version 2.1は、新規登録されたrowの場合、スクリプトファイルを実行して、バージョン固有の履歴を管理することになります。既にrowに登録されているスクリプトバージョンは重複して実行されません。
ここで注意することは、Flywayで管理されるSQLファイルは、Flyway Pluginが認識できるように、src/main/resources/db/migrationに保存する必要があり、Prefix Vは必ず大文字で作成しなければなりません。
FlywayはJVMで動作するアプリケーションならば、実行時にAPIを介して、上記のパスに保存されたSQLファイルで作業を行うこともでき、Mavenでアプリケーションとは別に実行することもできます。(Gradle、Antの両方についてもサポートしていますが、Mavenで説明します。)
Mavenを使用
- まず、Flyway依存性ライブラリをダウンロードします。(Spring bootはFlywayバージョンを管理するので、バージョンを指定しなくても構いません)
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>${flyway-core.version}</version> </dependency>
- 単体テスト実行時、H2にMigrationを進めています。
@BeforeClass public static void initDB() throws Exception { server = Server.createTcpServer(); initSchema(); } private static void initSchema() { Flyway flyway = new Flyway(); flyway.setDataSource(DB_URL, "sa", ""); flyway.migrate(); } @AfterClass public static void closeDB() throws Exception { server.shutdown(); }
参考までにSpring BootはCoC(Convention over Configuration)により、上のコードは必要なく、yamlファイルに以下の設定で単体テスト実行時にSQL Migrationが可能です。(H2 in-memory-db使用時、スキーマ形状がdefault H2でサポートしていないkeywordの場合があり、MODE属性で使用するDBMSを指定します)
spring: flyway: enabled: true username: sa datasource: driverClassName: org.h2.Driver url: jdbc:h2:mem:testdb;MODE=Mysql;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
アプリケーション実行時マイグレーション進行
- Applicaton main()メソッドに次のコードを追加します。
Flyway flyway = Flyway.configure().dataSource("DB_URL", "User", 'Password').load(); flyway.migrate();
アプリケーションの実行とは別にMaven Goalを利用してマイグレーションを進行
- POMにPluginを追加します。
<plugin> <groupId>org.flywaydb</groupId> <artifactId>flyway-maven-plugin</artifactId> <version>${flyway-maven-plugin.version}</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector-java.version}</version> </dependency> </dependencies> </plugin>
- flyway.confファイルに構成管理を反映する対象DBサーバーの情報記載した後、Mavenでマイグレーションを行います。
flyway.url=jdbc:mysql://toast.com:{Port}/{DB명} flyway.user=framework flyway.password= flyway.ignoreMissingMigrations=true flyway.validateOnMigrate=false $ mvn -Dflyway.configFiles=flyway.conf flyway:migrate
まとめ
サポート可能なDBは以下の通り、ほとんどのDBMSは対応しているので、利用中のDBが含まれている場合、使用を検討してみてください。
Google Cloud SQL, PostgreSQL (including Amazon RDS and Heroku), Redshift, Vertica, H2,
Hsql, Derby, SQLite, SAP HANA, solidDB, Sybase ASE, Phoenix…
マイグレーションファイルを変更明細基準で作成すると、協業の場合、ファイルが増えることもあります。そこで配布日が決まっている場合、V配布日付_説明.sql(例: V181116_deploy.sql)のように、1ファイルで管理するのが有効でファイル数も大きくならず便利です。
Flywayがcommunity(無料)、Pro、Enterprise(有料)バージョンに分かれていますが、形状管理はcommunityも十分適用できるので、まだ使用していない場合はHuman Faultを減らし、単体テストの効率UPのため使用を検討してみてください。
FlywayはDDL Script自体を支援しますが LiquibaseはXMLを利用するので、Flywayがより有用であると思います。