ちょっと硬派なコンピュータフリークのBlogです。

カスタム検索

2007-12-28

mod_dbd入門編

予てから手を着けようと思っていたApacheのデータベースコネクション管理モジュールであるmod_dbdの中身を覗いてみた。これはApache 2.1から(2.1はスキップされたので実質は2.2から)導入されたモジュールで、データベースのコネクションを管理してくれる。誰のために管理してくれるのか?それは他のモジュールのためにである。実は自分で作成したCGI等のWebアプリケーションがmod_dbdを明示的に使用することは出来ない。mod_dbdの機能を使用するのはApacheにロードされた他のモジュールである。例えばmod_authn_dbdPHPなどが使うことになる。なので、通常はApacheにロードされたモジュールが適宜使用してくれるので、あまり意識することなくその恩恵に与ることになる。そして殆どの人にとってはApacheモジュールを開発する機会がないだろうから、mod_dbdを使って開発をする機会もあまりないだろう。

ではどうしてそのようなモジュールの中身をわざわざ研究するのか?それは単に興味があるからである。

さて、前置きが長くなったがmod_dbdが具体的にどのようなことをしてくれるかというと、
  1. MySQLPostgreSQLSQLiteなどのデータベースドライバのラッパーになる。
  2. コネクションプール(未使用時にもコネクションをキープする機能)を実現する。
  3. マルチスレッド環境において、スレッドセーフなコネクション管理を実現する。
という3つが主要なものだろう。

つまり言い換えると、どんなDBMSに接続しているかを特別意識せずにアプリケーションの開発が行えるので移植性が高いコーディングができ、自前でコネクションプールを実装しなくてもそこそこ高い性能が得られ、スレッドセーフなのでデータベース操作時に排他制御をする必要がない、ということである。

具体的な使用法はmod_dbdのマニュアルページ↓に書いてあるのだが、イマイチ要領を得ない。
http://httpd.apache.org/docs/2.2/ja/mod/mod_dbd.html

以下の5つの関数をAPIとして解放しているのだが、一体どうやってクエリを実行するのだろうか?

AP_DECLARE(ap_dbd_t*) ap_dbd_open(apr_pool_t*, server_rec*);
AP_DECLARE(void) ap_dbd_close(server_rec*, ap_dbd_t*);
AP_DECLARE(ap_dbd_t*) ap_dbd_acquire(request_rec*);
AP_DECLARE(ap_dbd_t*) ap_dbd_cacquire(request_rec*);
AP_DECLARE(void) ap_dbd_prepare(server_rec*, const char*, const char*);

これではせっかくプリペアードステートメントの準備は出来ても、実際にそれを使用できないじゃないかと思うかも知れない。そもそもクエリを実行するAPIがないじゃないか?!と。

実はmod_dbdはapr_dbdで使用するためのコネクションを管理するだけなのである。ap_dbd_acquire関数などの引数になっているap_dbd_t構造体がミソで、その中身は次のようになっている。

typedef struct {
    apr_dbd_t *handle;
    apr_dbd_driver_t *driver;
    apr_hash_t *prepared;
} ap_dbd_t;

ap_dbd_tの中にはapr_dbd_tが格納されていて、これがapr_dbdが使用するコネクションハンドラとなる。後はapr_dbdの各種関数を利用して、データベース操作を行えば良い。(ap_dbd_tとapr_dbd_tの二つの構造体は一文字しか違わないので紛らわしい。)

apr_dbdについては下記のドキュメントを参照して欲しい。
http://apr.apache.org/docs/apr-util/1.2/group___a_p_r___util___d_b_d.html

以上のことから、mod_dbdの使用法をまとめると、
  1. httpd.confのディレクティブを用いて接続先やプールに関する設定をする。
  2. ap_dbd_acquire関数などを用いてコネクションハンドラを得る。
  3. apr_dbdを用いてデータベースを操作する。
となる。

そのうち暇をみつけたらmod_dbdを使ってサンデープログラマをする予定である。

0 コメント:

コメントを投稿