スマートスタイル TECH BLOG

データベース&クラウド技術情報

Skeema を使ってみた

Terraform や Kubernates のマニフェスト等、インフラ界隈ではより安全でバージョン管理可能、かつ自動化に組み込みやすい「宣言型」の方法での構築が流行ですが、MySQLにもサードパーティ製の宣言型スキーマ定義ツールであるSkeemaがありますので、今回試してみました。

検証環境

おなじみの dbdeployer で環境を作成します。
手元にあった 8.0.27 を使いました。

sakila database を検証用にインポートしておきます。

Skeema とは

MySQLスキーマオブジェクトをマニフェストファイルで宣言的に管理、変更する事ができるCLIツールです。

宣言型の構築手法が良い点として

  • マニフェスト = 実際の構成

という点があります。

スキーマ構成をキレイにドキュメントにまとめても、作ったそばから陳腐化していくことは避けられません。
可読性の高いマニフェストを使用していれば、変更作業とドキュメント化が同じ作業で行えるということで一石二鳥です。

また、Skeemaは内部的にオブジェクトに変更を加える際には pt-online-schema-change を使うというようにサービス影響を考慮して変更が加えられるようになっています。

Skeemaには、無償のCommunity版と、有償のPlus/Premium版があります。
無償と有償の大きな違いとしては、「ビュー、イベント、ルーチン、トリガ等が管理対象外になる」ということのようです。

Skeemaのインストール

Community Edition のページから.tar.gz版をダウンロードしました。
RPMやDEBも用意されています。

チュートリアル

まずは、 init サブコマンドを使用して、管理対象のデータベースインスタンスの情報をダンプし、任意のディレクトリに格納します。
今回は、skeemaディレクトリを作成し、サブディレクトリの schemas に初期化しました。

以下のようにファイルが作成されました。

作業は基本的に初期化したschemasディレクトリで行います。

最上位の.skeema ファイルには環境の接続情報が格納されています。

skeema add-environment コマンドで、新しい接続先を追加することが可能です。

.skeema を先頭の定義からデフォルトとして利用するため、環境名を指定しないコマンドはこの場合、productionに実行されます。
また、共通のオプションについては各セクションよりも前の先頭に記載することですべての環境に影響します。

.sqlファイルにはCREATE文が記載されています。
ファイルパスは environment/schema/table.sql となっており、目的のファイルを見つけることは容易でしょう。

sakila.actor に変更を加えてみようと思います。

MySQLのオブジェクトへ変更を加えるためには、通常 ALTER を実行しますが、Skeema で管理している場合は、ファイル内の CREATE 文を変更することで、ツールが必要なSQLを発行して目的の状態となります。

ですので、とりあえずnick_name列の追加をしてみます。

変更の差分は diff コマンドで確認できます。

address テーブルで警告がでていますが、空間インデックスがサポートされないためのようです。
ドキュメントによれば他の操作に影響するものではないということですので、無視して良さそうです。

またその次にactorテーブルにも警告が発生していますが、これは AUTO_INCREMENT 列が smallint で定義されているためのようです(一般的にintやbigintのunsignedが推奨です)。
このように、skeema では望ましくないスキーマ定義の Linter としての機能も持っています。

最後にテーブル定義を変更するための ALTER が自動生成されていることが確認できます。

実際に反映するためには、push サブコマンドを実行します。

以下の通り、反映されました。

diff サブコマンドを使用すれば、すべてのテーブルで差分が無いことを確認することができます。

なお、CREATE をする場合は、.sqlファイルを目的のスキーマのディレクトリに作成、DROPをする場合は、逆に.sqlファイルを削除して skeema pushすることになります。

DROPは危険な操作とみなされ、--allow-unsafe オプションを付ける必要があります。
これにより、意図せずにファイルが消えてしまったような際のセーフティネットになります。

また、.sqlファイルを変更する際に、人によって順序や書き方が変わったり、望ましくない設定を行う可能性がありますが、lint サブコマンドでそれを検知する事ができます。

また、format サブコマンドを実行することで、.sqlファイルを再フォーマットすることができます。
Github ActionsやGitlab CI/CD 等に加えて管理するのがよさそうです。

最後に、先程の空間インデックスのように、Skeemaが変更をサポートできていない機能が一部存在します。
そのような場合は従来どおりコマンドラインで実行することになるのですが、その後スキーマ情報を一致させるためのコマンドとして、 pull サブコマンドがあります。

直接データベース側をいじってみましょう。

pull コマンドによって、変更したテーブルの情報が取り込まれました。

データベースインスタンス側の情報が.sqlに反映されています。

別のインスタンスにも、同じスキーマ構成を反映させたいという場合は、環境を指定して push コマンドを実行します。

以下の通り、反映されました。

まとめ

現時点では、プレミアム版でも空間インデックス、ロールをサポートしていないなどの制限がありますので、このツールのみで宣言的にMySQLを構成するというのは難しい印象を受けました。

一方で、全ての操作がより安全に宣言的に実行できれば多くのメリットがあると思いますので、今後に期待したい製品だと思います。

Return Top