dbmate+SchemaSpyを組み合わせたマイグレーション管理
CircleCIでdbmate, tbls, PerconaToolkit, SchemaSpyを実行して、MySQLデータベースのマイグレーションとスキーマのlint、スキーマ定義書の自動生成を行います。 生成した定義書はS3+CloudFrontで配信します。
MySQL 5.7
- dbmate(https://github.com/amacneil/dbmate)
- tbls(https://github.com/k1LoW/tbls)
- Percona Toolkit(https://www.percona.com/software/database-tools/percona-toolkit)
- SchemaSpy(https://schemaspy.org/)
まずdb/baseline.sql
にデータベースの初期状態となるスキーマダンプファイルを格納します。既存のデータベースがなく新規で利用する場合は空のSQLファイルにします。このサンプルではSakila Sample Databaseを初期状態として利用しています。
dbmateでマイグレーションファイルを作成し、db/migrations/
以下に格納します。マイグレーションファイルが全く存在しないとdbmateがエラーになるため、回避策としてダミーのマイグレーションファイル20220304100126_dummy.sql
があります。このファイルはSQLコメントしかないので、実行しても何もおきません。
dbmateのマイグレーションファイルは名前の頭にyyyymmddhhmmssがつきます。dbmateはこの部分を見て、時間順にマイグレーションを実行していきます。
リポジトリにpushすると、まずdb/baseline.sql
をロードして、MySQLの初期設定が実行されます。MySQL起動が完了すると、dbmateで順次マイグレーションが実行されます。マイグレーション実行後にtbls, pt-duplicate-key-checkerが実行されます。デモなのでtbls.ymlでほとんどスルーしています。
tblsのあとpt-duplicate-key-checkerで重複したインデックスをチェックします。なお、pt-duplicate-key-checkerは重複したインデックスがあっても戻り値は0なので、テストは停止しません。
テスト実行後にSchemaSpyが実行されます。SchemaSpyの設定情報はschemaspy.properties
ファイルに記述されています。SchemaSpyの画像出力形式にはsvgとpngがありますが、画像の特性上ベクター形式のsvgのほうがきれいです。CircleCI Serverを使っている場合は、svg形式が表示できないこともあるようです。この場合はpng形式を利用するとよいでしょう。
他にもパラメータがあるので、SchemaSpy Command-Line Argumentsを参考にしてください。
なお公式に配布されているSchemaSpyのDockerイメージに同梱されているMySQL JDBCドライバーはバージョンが古いので、MySQL8.0では接続が
生成されたスキーマドキュメントはArtifactsにアップロードされます。Artifactsからindex.html
を選択すると、ドキュメントを参照できます。実行したマイグレーションが適切かどうか確認します。
mainブランチにマージしたときは、ArtifactsとあわせてS3に保存されます。このS3バケットをバックエンドとしたCloudFront経由でスキーマドキュメントが表示できます。このCloudFrontで配信されるドキュメントを現状の最新ドキュメントとみなします。S3アップロード後CloudFrontのキャッシュ無効化APIを実行し、古いファイルが表示されないようにしています。
tfディレクトリ内にOIDC認証用のIAM Role, Policyを作成するTerraformのテンプレートがあります。デモではS3とCloudFrontも利用していますが、都合によりテンプレートは入っていません。