開発時のAgileなデータベース管理とは?

http://www.dahlstroms.com
http://www.dahlstroms.com

dahlstroms from flickr

2011年に注目したい技術 – ThoughtWorks Technology Radarにまとめた内容の中に、Automated database deploymentというものがありました。自動化されたデータベースデプロイメントとでも訳すのでしょうか。どういうものなのか気になったので調べてみました。

Richard DingwallThe road to automated database deploymentという記事がありました。今年の2/9に書かれた記事で、最近担当したプロジェクトでTryした内容がまとめられています。

アプリケーションのファイルやウェブサイトは簡単に削除したり戻したりできますが、データベースはそこまで簡単にいじることができません。いざ、失敗したらバックアップからリロードし、データの再構築をしなければならなくなってしまいます。そんな中、彼はどのようにして自動化をデータベースデプロイに取り込んでいったのでしょうか?

ポータブルなスクリプトを使ったリリース

初めての大きなプロジェクトでは、開発者はDBのワーキングコピーを取ってきて、GUIツールなどで直接DBをいじっていたそうです。リリース日には、設計者がSQL比較ツールを使って、DEVと本番のDBを比較し、すべてのDB変更を反映するスクリプトを作って本番に反映していました。

いうまでもなく、この方法は、まぁ妥当な方法です。しかし、いくつか問題もあり、定期的に開発者はこの作業を行わなければならなくなってしまいます。

  • 環境の差異があると同じ差分確認スクリプトが使えなくなってしまう
  • 最終的に、スクリプトをソース管理するとしても、それまでに障害が発生した場合、すべての変更を失ってしまう
  • SQL比較ツールは、スキーマ変更をリバースエンジニアできるが、データ変更などは対応できないため、完璧なツールにならない

たしかに、スキーマは対応できても、テストデータがなくなるとデータの作り直しが発生します。個人でDBを操作していると、データも個人に依存してしまうでしょう。

データベースのバージョントラッキングするためのテーブルを用意する

まずは、以下のように、スクリプトの最後に、DBをバージョン管理するためのテーブルを用意し、その情報をInsertするようにしました。

https://gist.github.com/daipresents/d5038a00a4713171a915c0f9a6f6b443.js

こうすれば、どのスクリプトを実行する必要があるかすぐわかります。Railsのmigrationで使われるschema_infoテーブルに似ているやり方です。また、スクリプトの実行が失敗する場合は、このInsertをつけないようにして、成功したスクリプトだけが管理されるようにする必要があります。

データベースのバージョンの認知

読んでいて文の意図が読めなかったのですが、ChangelogテーブルやVersionテーブルによって、初期のデータベース作成が簡単になり、エラーなども容易に見つけることができるようになるということ?

スクリプトの恩恵

“すべてのDB変更スクリプトは、同じユーザで実行可能にすること”というルールを追加。アプリケーションごとに、専用接続ユーザを作るということでしょうか?このルールは、DBAに作業が依存しなくなり、rootパスワードの共有などもしなくてよくなるということを意味します。

スクリプトを実行するということは、DDLを操作する権限を与えるということです。今までは、特権を持った誰かにそうさしてもらうことで心配に思っていた部分があるはずです。これはDBを共有することではなく、アプリケーションの使い方を除外してしまうということです。このルールによって、責任を取り除き、自分たちで管理することができるようになります。

WordPressも自分でDBをアップグレードする形をとっており、偉大なるインターネット上で1200万ものサイトが稼動しているのもうなづけるとおもいます。

スクリプトがシステムを動かす必須要素であるならば、ストレージファイルやテーブルパーティショニングといったストレージやセキュリティも意味することになるでしょう。これらはアプリケーション実行には関係がない部分があり、それゆえ、公式のデータベースバージョンヒストリの一部分ではないともいえます。スクリプトは自動アップグレードの独立した実行を可能とします。

存在するインストールをきれいにする

スクリプトの共有によって、たくさんの種類のアプリケーションが存在することになり、様々な問題が発生することになります。誰でもDBをいじれるようになるとこうなってしまいますね。どのような自動化プロセスでも取り入れる前に、スクリプトを使わない人が現れたり、DBAのがアドホックにスクリプトを修正したり、CHANGELOGテーブルを管理出来ていないと、しっかりしたプラットフォームをつくることは難しいです。昔はSQL比較ツールを使って手で確認していましたが、スクリプトの影響かたくさんの環境ができてしまった。そこで、自動化スクリプトにクリーンアップ処理を入れたくなるかもしれません。

自発的にアップグレードするアプリケーション

自動アップグレードを実装することは比較的に簡単です。CHANGELOGテーブルをチェックし、まだ実行していないスクリプトを探し出せばいいのです。この方法だと、前のバージョンのDBにはマイナスとなります。我々のアップグレードツールは、クリーンアップ処理や、例えばCHANGELOGテーブルを作成する処理、必要であれば、以前のバージョンのデータベースの不要なデータやテーブルの消去など、たくさんの前処理を行います。

このプロセスは、人の手作業よりも、単体でテストされ、過程の監査となるようにデザインされています。これで、何百回も不安なしでスクリプトが実行出来るようになります。このスクリプトの処理は、継続的インテグレーションや、自動テストといったプロセスの一部にすることが可能で、そうすべきだと思います。

失敗やバックアップ

スクリプトは信頼に足りるものなのですが、リリース日には不幸がつきものです。手作業となる部分でバックアップを失ってしまったので、はじめる前にバックアップする処理を追加しました。最終的には、実行に失敗したときにロールバックするような処理をスクリプトに加えようと考えています。

最後に

この方法が自動データベースデプロイを手に入れる方法だとは思いませんが、これは必須の方法だと考えています。今も、課題を改善していますが、今までのところ、とてもいい感じでスクリプトは我々を手助けしてくれています。

*

Railsを使うと、migrationががんばってくれるが、フレームワークによっては、こういったスクリプトを活用することが重要だと思います。私は、この人のブログを読んでいて、

  • 自動化することの重要性
  • 自動化に頼るだけではなく規律も重要
  • もちろん、改善も重要

だと感じました。こういったプロジェクトを円滑にすすめるために、プロセスを考えることも、プロジェクトの成功には必須の要素だと思います。