タグ別アーカイブ: database

自動的にデータベースを移行!?「LiquiBase」

| コメントをどうぞ

バファリンの半分は優しさでできているそうですが、
データベースの半分は怒りでできています。

お久しぶりです。DiceK Mikamiです。

データベースと言えばデータを永続化させるための魔法の箱ですが、運用者や開発者たちはこれのおかげで夜も眠れない日々を送ることが多々あります。
パフォーマンスチューニング、スキーマ構成、インデキシング、サイジング、etcetc…
その中でも今回はデータベース移行に関して取り上げたいと思います。
データベース移行はそれほど頻繁に行われる作業ではありませんが、いざ発生すると頭を抱える事態が往々にしておきます。
運用者は「参照整合性が〜」となり、開発者は「移行ツールが〜」となるわけです。
平たく言うと、「ちょ〜めんどくさい」なのです。

これらを緩和するために「LiquiBase」というデータベースリファクタリングツールを紹介したいと思います。
このツールでは、簡単なXMLでデータベースのマイグレーションや変更管理などを行うことができます。
また、対応データベースも非常に多くMySQLなどのオープンソースデータベースからOracle、IBM DB2などと言った商用データベースまでカバーしています。
実行方法もコマンドライン、Ant、Maven、サーブレットリスナーなどと多岐にわたっております。

今回はWebアプリケーション起動時に自動的にマイグレーションを行ってくれる方法(サーブレットリスナーによる実行)をサンプルにご紹介したいと思います。
(コマンドライン実行の方が簡単です。そちらに関しては参考URLより確認してみて下さい)
 
 

検証環境

OS: Mac OSX 10.7.4 Lion
Java: JDK1.6.0_33 64bit
APサーバ: Tomcat6
DB: MySQL 5.5.21
LiquiBase: version 2.0.5
 
 

検証

サンプルとして以下のPersonテーブルを既存データベースに追加してみたいと思います。

Person
Field Type Null Key Default
id int(11) NO PRI NULL
name varchar(50) NO NULL
age int(3) YES NULL

 
1. Database Change Logの作成
LiquiBaseでは、Database Change LogというXMLでデータベースの変更履歴を管理します。
これは公式ページに書き方やサンプルがありますので、そちらを参考にして下さい。
参考にしてできたXMLは以下のようなものになります。

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd
    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <changeSet id="sample_liquibase" author="dicekmikami">
        <createTable tableName="person">
            <column name="id" type="int">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="age" type="int(3)">
                <constraints nullable="true"/>
            </column>
        </createTable>
    </changeSet>

</databaseChangeLog> 

このファイルを「 WEB-INF/db/db.changelog-1.0.xml 」として保存します。
 
2. web.xmlの設定
サーブレットリスナーで実行するために、アプリケーションのweb.xmlにも記述する必要があります。
以下は追加で記述するものです。
(下部に利用した接続情報設定も記載してあります。)

    <context-param>
        <param-name>liquibase.changelog</param-name>
        <param-value>../db/db.changelog-1.0.xml</param-value>
    </context-param>
    <context-param>
        <param-name>liquibase.datasource</param-name>
        <param-value>java:comp/env/jdbc/liquibasesample</param-value>
    </context-param>
    <context-param>
        <param-name>liquibase.should.run</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>liquibase.onerror.fail</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>liquibase.schema.default</param-name>
        <param-value></param-value>
    </context-param>
    <listener>
        <listener-class>liquibase.integration.servlet.LiquibaseServletListener</listener-class>
    </listener>
    
    <resource-ref>
        <res-ref-name>jdbc/liquibasesample</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

一応、context.xmlも載せておきます。

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/liquibase-sample" reloadable="false" >
        <Resource name="jdbc/liquibasesample"
                  auth="Container"
                  type="javax.sql.DataSource"
                  driverClassName="com.mysql.jdbc.Driver"
                  url="jdbc:mysql://localhost:3306/liquibasesample?useUnicode=true&amp;characterEncoding=UTF-8"
                  username="root"
                  password=""
                  validationQuery="select 1" />
</Context>

既存データベースのサンプルとして「 liquibasesample 」というデータベースを用意しました。
 
3. ライブラリの設置
必要な記述は以上で終わりですが、ライブラリの設置が必要になります。
ライブラリはLiquiBase公式からダウンロードしてきた圧縮ファイルのなかにjarファイルがありますので、それをアプリケーションの中に入れておきます。
もちろんデータベースとの接続が必要になりますので、データベース接続ライブラリも別途必要になります。

4. 結果
さて、これで起動するたびにマイグレーションが実行されるようになりました。
早速起動してみましょう。


〜 前略 〜

情報: Webアプリケーションアーカイブ Liquibase-Sample.war を配備します
INFO 12/09/04 11:42:liquibase: Successfully acquired change log lock
INFO 12/09/04 11:42:liquibase: Creating database history table with name: `DATABASECHANGELOG`
INFO 12/09/04 11:42:liquibase: Reading from `DATABASECHANGELOG`
INFO 12/09/04 11:42:liquibase: Reading from `DATABASECHANGELOG`
INFO 12/09/04 11:42:liquibase: ChangeSet ../db/db.changelog-1.0.xml::sample_liquibase::dicekmikami ran successfully in 124ms
INFO 12/09/04 11:42:liquibase: Successfully released change log lock

〜 後略 〜

catalinaログを見ると、上記のようなログが見れると思います。
実際のデータベースの中身を見てみます。

しっかりできています。
DATABASECHANGELOGテーブルはLiquiBaseによって自動的に作成されるテーブルです。
この中に変更履歴が含まれていますので、同じ変更履歴が実行されないようになっています。
 
以上が、LiquiBaseのサーブレットリスナーによる動的マイグレーションの手法となります。
個人的には「やった!これで移行ツールのマニュアル書かなくて良い!」なのですが、変更管理や参照整合性を保った変更などをツールが肩代わりしてくれるというだけでも十分に魅力的なツールだと思います。
 
 

参考URL

LiquiBase
DBAを救え! DBリファクタリングツール「LiquiBase」を使ってみよう