Help us understand the problem. What is going on with this article?

Flyway で MySQL のバージョン管理をしてみる in docker-compose

More than 1 year has passed since last update.

背景

デプロイやらローカル環境やらでいくつか不便なことが発生している今日この頃。

  1. アプリをデプロイするたびに、DBの変更差分をSVNのログから目視で探していた。
  2. viewの更新を手作業で実行しており、稀に誤って全tableを初期化する事態が発生していた。
  3. それぞれの環境でどこまでDBの変更が適用されているのかよくわからない。
  4. 作業者の開発環境のDBに差分を適用することが面倒。
  5. デプロイ作業の自動化を進めたい。

といった問題の対応策として flyway を検討してみる。
※ ビルドツールなんてものは存在しない環境なのでプラグインは使えません。

最終的な姿はこちら

構成

  • DB
    • MySQL 8.0.15
  • Flyway

    • Flyway Community Edition 5.2.4 by Boxfuse
  • 最終的なDirectory構成

sample-flyway
│  docker-compose.yml
│
├─flyway
│  ├─conf
│  │      flyway.conf
│  └─sql
│          V0.000__Baseline.sql
│          V1.001__Create_table_test.sql
│          V1.002__Insert_table_test.sql
│          V2.001__Create_person_table.sql
└─mysql
    └─initdb.d
            schema.sql

DBの準備

まずは MySQL 単体で動作確認する。

docker-compose.yml
version: '3.4'

services:
  mysqldb:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: sample_db
      MYSQL_ROOT_USER: root
      MYSQL_ROOT_PASSWORD: pass

起動して接続できることを確認する。

[sample-flyway]$ docker-compose up -d mysqldb
Creating network "sampleflyway_default" with the default driver
Creating sampleflyway_mysqldb_1 ... done

[sample-flyway]$ docker-compose ps
       Name                     Command             State          Ports
-------------------------------------------------------------------------------
sampleflyway_mysqldb_1   docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp

[sample-flyway]$ docker-compose exec mysqldb mysql -u root -p -e 'show databases;'
Enter password:
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sample_db          |
| sys                |
+--------------------+

DBが動くことを確認。

Flywayの準備

docker-compose.ymlflyway の記述を追加する。

docker-compose.yml
version: '3.4'

services:
  mysqldb:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: sample_db
      MYSQL_ROOT_USER: root
      MYSQL_ROOT_PASSWORD: pass
  # === ココカラ ===
  migratedb:
    image: boxfuse/flyway:latest
    volumes:
      - ./flyway/sql:/flyway/sql
      - ./flyway/conf:/flyway/conf
    depends_on:
      - mysqldb
    command: migrate
  # === ココマデ ===

設定ファイルを用意する。

flyway.conf
flyway.url=jdbc:mysql://mysqldb:3306/sample_db
flyway.user=root
flyway.password=pass

差分のSQLを用意する。

V1.001__Create_table_test.sql
CREATE TABLE v1_difference_application (id INT);
V1.002__Insert_table_test.sql
INSERT INTO v1_difference_application VALUES(100);
INSERT INTO v1_difference_application VALUES(101);
V2.001__Create_person_table.sql
CREATE TABLE person (id INT NOT NULL, name VARCHAR(100) NOT NULL);

マイグレーションしてみる。

[sample-flyway]$ docker-compose run --rm migratedb
Starting sampleflyway_mysqldb_1 ... done
Flyway Community Edition 5.2.4 by Boxfuse
Successfully validated 3 migrations (execution time 00:00.039s)
Creating Schema History table: `sample_db`.`flyway_schema_history`
Current version of schema `sample_db`: << Empty Schema >>
Migrating schema `sample_db` to version 1.001 - Create table test
Migrating schema `sample_db` to version 1.002 - Insert table test
Migrating schema `sample_db` to version 2.001 - Create person table
Successfully applied 3 migrations to schema `sample_db` (execution time 00:00.358s)

成功した。DBを確認する。

[sample-flyway]$ docker-compose exec mysqldb mysql -u root -p -D sample_db -e 'select * from v1_difference_application;'
Enter password:
+------+
| id   |
+------+
|  100 |
|  101 |
+------+

マイグレーションできた。よかった。
docker-compose down で停止しておく。

新規作成以外の場合はどうする?

既存システムの場合は既にテーブルやデータが作られてしまっているので、上記手順では「既にデータベースが作られてるよ」と言われマイグレーションできない。
そのため、ベースラインとして既にある構造の分を設定することで、そこからの差分を管理してもらうことができる。

docker-compose up -d mysqldb でDBを起動しておく。

既存DBのSQLを追加

V0.000__Baseline.sql
CREATE TABLE init_table (id INT);

migratedb サービスの commandinfo で上書きして初期状態を確認する。

[sample-flyway]$ docker-compose run --rm migratedb info
Starting sampleflyway_mysqldb_1 ... done
Flyway Community Edition 5.2.4 by Boxfuse
Schema version: << Empty Schema >>

+-----------+---------+---------------------+------+--------------+---------+
| Category  | Version | Description         | Type | Installed On | State   |
+-----------+---------+---------------------+------+--------------+---------+
| Versioned | 0.000   | Baseline            | SQL  |              | Pending |
| Versioned | 1.001   | Create table test   | SQL  |              | Pending |
| Versioned | 1.002   | Insert table test   | SQL  |              | Pending |
| Versioned | 2.001   | Create person table | SQL  |              | Pending |
+-----------+---------+---------------------+------+--------------+---------+

StatePending になっている。
ベースラインを設定してみる。

[sample-flyway]$ docker-compose run --rm migratedb baseline -baselineVersion=0_000 -baselineDescription=Baseline
Starting sampleflyway_mysqldb_1 ... done
Flyway Community Edition 5.2.4 by Boxfuse
Creating Schema History table: `sample_db`.`flyway_schema_history`
Successfully baselined schema with version: 0.000


[sample-flyway]$ docker-compose run --rm migratedb info
Starting sampleflyway_mysqldb_1 ... done
Flyway Community Edition 5.2.4 by Boxfuse
Schema version: 0.000

+-----------+---------+---------------------+----------+---------------------+----------+
| Category  | Version | Description         | Type     | Installed On        | State    |
+-----------+---------+---------------------+----------+---------------------+----------+
|           | 0.000   | Baseline            | BASELINE | 2019-03-26 06:57:18 | Baseline |
| Versioned | 1.001   | Create table test   | SQL      |                     | Pending  |
| Versioned | 1.002   | Insert table test   | SQL      |                     | Pending  |
| Versioned | 2.001   | Create person table | SQL      |                     | Pending  |
+-----------+---------+---------------------+----------+---------------------+----------+

Baseline が設定できた。
マイグレートしてみる。

[sample-flyway]$ docker-compose run --rm migratedb
Starting sampleflyway_mysqldb_1 ... done
Flyway Community Edition 5.2.4 by Boxfuse
Successfully validated 4 migrations (execution time 00:00.065s)
Current version of schema `sample_db`: 0.000
Migrating schema `sample_db` to version 1.001 - Create table test
Migrating schema `sample_db` to version 1.002 - Insert table test
Migrating schema `sample_db` to version 2.001 - Create person table
Successfully applied 3 migrations to schema `sample_db` (execution time 00:00.241s)


[sample-flyway]$ docker-compose run --rm migratedb info
Starting sampleflyway_mysqldb_1 ... done
Flyway Community Edition 5.2.4 by Boxfuse
Schema version: 2.001

+-----------+---------+---------------------+----------+---------------------+----------+
| Category  | Version | Description         | Type     | Installed On        | State    |
+-----------+---------+---------------------+----------+---------------------+----------+
|           | 0.000   | Baseline            | BASELINE | 2019-03-26 06:57:18 | Baseline |
| Versioned | 1.001   | Create table test   | SQL      | 2019-03-26 06:57:59 | Success  |
| Versioned | 1.002   | Insert table test   | SQL      | 2019-03-26 06:57:59 | Success  |
| Versioned | 2.001   | Create person table | SQL      | 2019-03-26 06:57:59 | Success  |
+-----------+---------+---------------------+----------+---------------------+----------+

StateSuccess になった。よかった。

+alpha

  1. k8sの初期化コンテナにするとか
  2. CI/CDツールでコミット検知して自動マイグレーションするとか

してみると楽しいかもしれない。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした