印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
Linux mod_perl で DB_File が動かない

Apache に mod_perl を導入すると、MovableType の編集モードの動作が速くなるらしい。Vine Linux の場合、mod_perl はインストールできるのだが、Movable Type が動かない。DB_File.pm 関連のエラーが出てしまう。最終的には、簡単な設定をするだけで動作することが分かった。しかし、それまでの道が長かった。

■ ■ ■

mod_perl の環境で MT を動作させる方法については、オリジナルのマニュアル その他の環境 - mod_perl に記述がある。導入事例を紹介しているサイトには MovableType を mod_perl (Apache::Registry) 環境下で動かす方法 : NDO::WeblogFenrir's BLog: mod_perlで高速化 があり、大変分かりやすく解説されている。しかし、まずはマニュアルにしたがってやってみたい。

環境は Vine Linux 2.6、Movable Type 2.661 で、Movable Type では Berkeley DB を使うとする。

まず、Apache のインストール状況を確認する。

$ /usr/sbin/httpd -l
Compiled-in modules:
  http_core.c
  mod_so.c
suexec: disabled; invalid wrapper /usr/sbin/suexec

mod_so.c が表示されているので、DSO (Dynamic Shared Object) に対応していることが分かる。DSO の場合、起動時に動的にモジュールを読み込むため、新しいモジュールを追加する場合でも Apache を再コンパイルする必要がない。

mod_perl をインストールする。すでにインストールされているかは、/etc/httpd/modules ディレクトリに libperl.so があるかどうかで判断することができる。あればインストール済みである。存在しない場合は新規インストールを行う。mod_perl は VinePlus に収録されているので、近くの Ring サーバを選んでダウンロードし、

$ wget ftp://core.ring.gr.jp/pub/linux/Vine/VinePlus/2.6/RPMS/i386/mod_perl-1.26-6vl0.i386.rpm

普通にインストールすることができる。

# rpm -ivh mod_perl-1.26-6vl0.i386.rpm

動作を確認するには、/etc/httpd/conf/httpd.conf を編集し、<IfModule mod_perl.c> ... </IfModule> の間に赤色部分を追加する。

<IfModule mod_perl.c>
<Location /perl-status>
  SetHandler perl-script
  PerlHandler Apache::Status
</Location>

</IfModule>

構文チェックを行って再起動する。

# /etc/init.d/httpd configtest
Syntax OK
# /etc/init.d/httpd restart

上で設定したロケーションに、ブラウザでアクセスする。

http://nlogn.ath.cx/perl-status/

Apache::Status の画面になり「Embedded Perl version v5.6.1 for Apache/1.3.27 (Unix) (Vine/Linux) mod_ssl/2.8.14 OpenSSL/0.9.6m mod_perl/1.26 process 31198」などと表示されれば成功である。「Loaded Modules」をクリックすると、メモリにロードされているモジュールの一覧が表示される。

Devel::Symdump モジュールがインストールされていれば、さらにパッケージの内容まで見られるので楽しい。Devel::Symdump の導入は CPAN からネットワークインストールするのが便利。

# perl -MCPAN -e "install 'Devel::Symdump'"

動作確認が終わったら、セキュリティ向上のために、httpd.conf を編集して上記で追加した部分を削除するか、Location で指定した perl-status という名称を変更しておく方がいいかも知れない。Apache 関連の情報がかなり分かるからである。

mod_perl がインストールできたので、その上で Movable Type を動作させる準備を行う。マニュアルには Apache::Request とApache::Cookie モジュールが必要だとある。CPAN から Apache::Request をインストールしようとしたが、最後の make test で失敗してしまう(後に分かったことだが,LANG=C によって言語の設定を解除しておけば make test を通すことができる)。そこで、Apache HTTP Request Library - The Apache HTTP Server Project から libapreq-1.3 をダウンロードする。

$ wget http://nagoya.apache.org/mirror/httpd/libapreq/libapreq-1.3.tar.gz

コンパイルして問題なくインストールすることができる。

$ tar zxf  libapreq-1.3.tar.gz
$ cd libapreq-1.3
$ ./configure
$ perl Makefile.PL
$ make
$ make test
$ su
# make install

準備ができたので、/etc/httpd/conf/httpd.conf を編集し、上記の perl-status の下に次のコードを追加する (perl-status 部分は省略)。このサイトでは Movable Type の CGI のディレクトリを opentype という名前にしている。

<IfModule mod_perl.c>
<Perl>
  use lib '/home/httpd/html/opentype/lib';
  use lib '/home/httpd/html/opentype/extlib';
</Perl>

Alias /opentype/ /home/httpd/html/opentype/
PerlModule Apache::Registry
<Location /opentype>
  SetHandler perl-script
  PerlHandler Apache::Registry
  Options +ExecCGI
</Location>

</IfModule>

Vine Linux では、何故か「PERL5LIB」でのライブラリ指定ができなかった。そこで、「use lib」を使って同じ動作をさせた。ライブラリを読み込んでいるかについては、perl-status の「Apache::Status」画面で「Loaded Modules」をクリックし、一番したの「@INC」にディレクトリが追加されているかどうかで確認することができる。

最初は、この追加コードをバーチャルサーバの中に書いていたのだが、違うバーチャルサーバでも mod_perl が有効になっていたので、バーチャルサーバ内に追加するのは止めにした (逆に考えれば、複数のバーチャルサーバで異なる設定の mod_perl を動作させることは難しいということか)。

これで完了のはずなので、動作確認のために Movable Type の編集画面にアクセスした。するとエラーが表示された。

Content-Type: text/html

Got an error: Unsupported driver MT::ObjectDriver::DBM:
DB_File needs compatible versions of libdb & db.h
        you have db.h version 3.2.9 and libdb version 2.4.14
Compilation failed in require at /home/httpd/html/opentype/lib/MT/ObjectDriver/DBM.pm line 9.
BEGIN failed--compilation aborted at /home/httpd/html/opentype/lib/MT/ObjectDriver/DBM.pm line 9.
Compilation failed in require at (eval 9) line 1.
BEGIN failed--compilation aborted at (eval 9) line 1.

メッセージを読むと、「MT::ObjectDriver::DBM」モジュールを使用する際に「DB_File」を読み込むのだが、これがエラーを吐いていることになっている。DB_File が読み込もうとするライブラリとヘッダファイルのバージョンが合っていないというのである。ヘッダ db.h のバージョンは 3.2.9 で、ライブラリ libdb のバージョンは 2.4.14 なのである。

そこで、DB_File がリンクしているファイルを調べてみることにした。

$ ldd /usr/lib/perl5/5.6.1/i386-linux/auto/DB_File/DB_File.so
        libdb-3.2.so => /lib/libdb-3.2.so (0x4000b000)
        libc.so.6 => /lib/libc.so.6 (0x400b8000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

libdb-3.2.so がリンクされている。したがって、Apache が起動時に読み込んでいるライブラリがマズそうだということが分かる。何故 libdb-2.4 などを読み込んでしまうのだろうか。mod_perl を使わなければ、問題なく DB_File は libdb-3.2 を使ってくれるのである。

Vine Linux のデータベース用ライブラリを調べてみると、db1, db2, db3 がインストールされていることが分かった。

$ rpm -qa | grep ^db
db3-3.2.9-1vl2
db1-1.85-5vl2
db1-devel-1.85-5vl2
db2-2.4.14-5vl2
db2-devel-2.4.14-5vl2
db3-devel-3.2.9-1vl2
db3-utils-3.2.9-1vl2

以下のような試行錯誤を行った。

  • db1, db2 を削除してはどうか?
    - db1 も db2 も削除してしまうと動かなくなるアプリケーションが山ほどある (Apache は db2 を使っている)
  • DB_File を db2 でコンパイルしてはどうか?
    - 手間がかかりそう
  • db.h ヘッダを db2 のヘッダに変えてはどうか?
    - /usr/include/db.h は /usr/include/db3/db.h にシンボリックリンクされているので、これを db2/db.h に変更してみたが、状況は変わらない
  • httpd.conf に LD_LIBRARY_PATH 指定して db3 を読み込ませてはどうか?
    - db3 は /lib/libdb.so にシンボリックリンクされているので、「SetEnv LD_LIBRARY_PATH /lib」を追加してみたが、変化なし
  • ライブラリの検索順の最初に db3 のある /lib を指定してはどうか?
    - /etc/ld.so.conf を編集し、最初の行に /lib を挿入して、ldconfig コマンドを発行したが変化なし

ここまでやっても上手く行かない。英語のサイトも探したが「どうしたらいい?」の質問ばかり。途方に暮れていたのだが、「Apache を起動する前に db3 ライブラリを読み込めばいいのではないか」ということに気がついた。

/etc/sysconfig/apache ファイルを新たに作り、中に次のように書いておく。

export LD_PRELOAD=/lib/libdb.so

起動スクリプト /etc/init.d/httpd は、/etc/sysconfig/apache ファイルがあれば最初に読み込むようになっている。直接起動スクリプトに追加するより美しい。

これで問題が解決した。めでたく mod_perl の上で Movable Type が動作するようになった。

編集画面が表示され、新規エントリの作成や再構築もできるようになったのだが、「B」や「i」などの編集ボタンが表示されないことが分かった。そこで、<File> ディレクティブを使って、mod_perl を使うのは拡張子が .cgi のファイルだけに限定しようとしたところ、「<Location> ディレクティブ内では <File> ディレクティブは使えない」というエラーで Apache の起動に失敗した。<File> ディレクティブを使いたいのであれば、<Directory> ディレクティブを使わなければならないのである。

最終的には以下のようになった。

<IfModule mod_perl.c>
<Perl>
  use lib '/home/httpd/html/opentype/lib';
  use lib '/home/httpd/html/opentype/extlib';
</Perl>

PerlModule Apache::Registry
<Directory /home/httpd/html/opentype>
<Files *.cgi>
  Options +ExecCGI
  SetHandler perl-script
  PerlHandler Apache::Registry
  PerlSendHeader Off
</Files>
</Directory>

</IfModule>

ここまで来て、なぜ他のサイトで <Directory> ディレクティブを使っている意味が分かったのである。分かるのが遅すぎる。「PerlSendHeader Off」については検討中。

現在、このサイトの記事は243個ある。ThinkPad 600 (Pentium II 233 MHz, メモリ 160 MB) [仕様: PCサポート - ThinkPad 600(2645-41J) - 製品仕様] ですべてを再構築すると7分かかる。mod_perl を導入して、再度計測してみたが、同じ7分であった。再構築の時間は速くならないようだ。ただし、編集メニューの表示、プレビュー表示などの速度は劇的に向上した。記事は増える一方であるが、全体を再構築しなければ記事の構築時間は今と変わらないはずである。だがしかし…。今後どうやって運用していくか悩むところである。

CGI の高速化には SpeedyCGI という方法もある。MovableType の高速化としては、Barkeley DB を捨てるという方法もあるようだ。

2005年11月12日追記:
Vine Linux 3.2 (kernel 2.4.31) では mod_perl を上手く導入できなかったため,Speedy CGI の後継である PersistentPerl を導入しました(nlog(n): mod_persistentperl で Movable Type を高速化)。

Posted by n at 2004-08-05 02:52 | Edit | Comments (0) | Trackback(4)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
[日記/blog] Vine Linux + mod_perl で Movable Type (2)
「Vine Linux + mod_perl + Movable Type (1)」の続き。 DB_File を試しに最新版にバージョンアップしてみたがやはりダメなので、結局 DB_File を使うことを諦めて MySQL 化する方向でなんとか解決。(後日追記: DB_File が使えない問題を解決された方がいたので参考リンク... Trackbacked from: スペースモラトリアムノカミサマ at November 06, 2004 00:47
mod_perl導入
MovableTypeをカスタマイズするたびに再構築が必要であるが、 この作業が... Trackbacked from: Kblog at December 21, 2004 14:42
mod_perlによる高速化
エントリをPHPモジュール化してそれなりに高速化できたのだが、まだまだ遅い。金がない奴は工夫して速くするしかない。どうにかならんのかと思っていたら、Movable Type を mod_perl で高速化する - Apache::Registry 編という記事があるじゃないか。 このページではApach... Trackbacked from: おやじまんのだめだこりゃ日記 at January 05, 2005 17:48
[linux]mod_perl入れた
mod_perlインスコ成功した。 とりあえず手順を書いておこう。   1.Apache::Requestをインスコ $ perl -MCPAN -e shellcpan> install Apache::Request2.httpd.conf を編集 <IfModule mod_perl.c><Perl>  use lib '/home/httpd/html/opentype/li Trackbacked from: ぼくも ゆうめいに なりたい at March 07, 2005 13:55
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?