[PHP-dev 156] Re: PostgreSQL Session Save Handler Module.

Youichi Iwakiri php-dev@php.gr.jp
Thu, 20 Dec 2001 09:50:18 +0900


いわきりです

Yasuo Ohgaki wrote in <3C1F6C77.3000101@yahoo.co.jp>:
 >PHP4.2.0-dev (CVS version)用のPostgreSQL Session Moduleを作りました。
 >今はプリミティブな状態ですが、GCをResource Shutdownに移動するなどすると
 >に非常にロードの高いWebサイトではGC時のページ表示の遅れなどが解消できます。
 >(これはそのうち変更するつもりです)

session.save_handler = files
session.save_path = /tmp 
と比べ
session.save_handler = pgsql
session.save_path = "host=localhost dbname=php_session user=www"
だと体感的には立ち上がり(初期接続時)は重く感じられました。
以降の操作での遅さは感じませんでした。

 >まだ、あまりテストしていません。興味のある方は人柱になっていただけると助か
 >ります。特にビルド(configure)の問題があるかも知れません。

ちと古いですが、
PHP-4.2.0-dev (php4-200111290000のsnapshot)にpatchを当てましたが
問題無く./buildconf, ./configure, gmakeが通りました。

下記環境での結果です。
  OS:         FreeBSD 3.4-RELEASE with PAO3
  GCC:        gcc 2.95.2
  make:       GNU Make version 3.77
  flex:       2.5.4
  Bison:      GNU Bison version 1.25
  Apache:     Apache 1.3.20
  PostgreSQL: PostgreSQL 7.1.3

 >リクエストがあれば、テーブルがDBに存在しない場合、テーブル作成の自動実行
 >なども付け加えます。

ここは、意見の分かれる箇所かも知れません。
個人的には、wwwのownerにはDB作成権限、テーブル作成権限を付与したく
ないと考えています。
今回試した限りでは、SELECT, UPDATE, DELETEのみ付与しました。

 >英文ですが、README.MOD_PGSQLに簡単な説明が書いてあります。
 >もし、試してみてバグを見付けた場合はご連絡いただけると助かります。

バグでは無いのですが、挙動が気になる部分があります。

Apacheの起動はrootよりapachectlで行っています。
httpd.confでは
MinSpareServers 5
MaxSpareServers 10
StartServers 5
とし、実際に動いているプロセスは下記の通りです。
iwa# ps -aux | grep httpd
root       712  0.0  3.1  5388 3988  ??  Ss    9:06AM   0:00.12 /usr/local/apache/bin/httpd
www        714  0.0  3.1  5388 3996  ??  S     9:06AM   0:00.00 /usr/local/apache/bin/httpd
www        715  0.0  3.1  5388 3996  ??  S     9:06AM   0:00.00 /usr/local/apache/bin/httpd
www        716  0.0  3.1  5388 3996  ??  S     9:06AM   0:00.00 /usr/local/apache/bin/httpd
www        717  0.0  3.1  5388 3996  ??  S     9:06AM   0:00.00 /usr/local/apache/bin/httpd
www        718  0.0  3.1  5388 3996  ??  S     9:06AM   0:00.00 /usr/local/apache/bin/httpd

以上の環境で、
session.save_handler = pgsql
session.save_path = "host=localhost dbname=php_session"
の設定で接続しsession管理を行うと

/usr/local/pgsql/bin/postmaster: BackendStartup: pid 445 user root db php_session socket 5
/usr/local/pgsql/bin/postmaster child[445]: starting with (postgres -d2 -v131072 -p php_session )
FindExec: found "/usr/local/pgsql/bin/postgres" using argv[0]
DEBUG:  connection: host=127.0.0.1 user=root database=php_session
DEBUG:  InitPostgres
FATAL 1:  user "root" does not exist
DEBUG:  proc_exit(0)
DEBUG:  shmem_exit(0)
DEBUG:  exit(0)
/usr/local/pgsql/bin/postmaster: reaping dead processes...
/usr/local/pgsql/bin/postmaster: CleanupProc: pid 445 exited with status 0

となり、user=rootとなりmod_pgsql内でロックしているように
見受けられます。(Apacheからのレスポンスが返ってこない状態)

session.save_handler = pgsql
session.save_path = "host=localhost dbname=php_session user=www"
と指定すれば問題ありません。

また、pgsql.soを利用してのDB接続はuserを指定しなくても
user=wwwと認識され問題無く動作しています。どうも先程のpsの
プロセスID = 712
でmod_pgsqlはPostgreSQLと接続しようとしていますが
これはそういうものなのでしょうか?

その他、GCがらみで思った点ですが、
PostgreSQLの現仕様上致し方無いのですが、GCを行い無効SESSIONIDを
削除してもテーブルサイズは肥大化していく一方なので、先に述べた
「個人的には、wwwのownerにはDB作成権限、テーブル作成権限を付与したく
 ないと考えています。」
とは裏腹にvacuumの自動実行をmod_pgsqlに機能として追加する必要性も
ありかなと思います。

以下は単純に1クライアントからセッション管理を行うページへ対し
30回弱アクセスした場合のテーブルの不要領域の情報です。
#不要領域の情報取得にはpgstattupleを利用しました。
ftp://ftp.sra.co.jp/pub/cmd/postgres/pgstattuple/pgstattuple-0.1.tar.gz

php_session=# select pgstattuple('php_session');
NOTICE:  physical length: 0.01MB live tuples: 1 (0.00MB, 2.51%) dead tuples: 24 (0.00MB, 56.36%) overhead: 41.13%
  pgstattuple   
----------------
 56.35986328125
(1 row)

php_session=# select pgstattuple('php_session');
NOTICE:  physical length: 0.01MB live tuples: 1 (0.00MB, 2.51%) dead tuples: 28 (0.01MB, 66.48%) overhead: 31.01%
  pgstattuple  
---------------
 66.4794921875
(1 row)

当然といえば当然なのですが、live tuplesが1なのは、1クライアントしか
接続していないからなのですが、dead tuplesはページ遷移を行う度に
増加して行きます。この問題をクリアしないことにはなかなか導入に
踏み切れないのではと考えてしまいます。

Webサーバのロードバランシングを行っている場合など個々のサーバで
セッション管理を行うと不整合が発生するケースもありますので、Webサーバの
裏に単一のセッション管理サーバを置くという点では非常に有効な機能の
提供になりますのでお手伝いできることがあればお手伝いさせていただきます。

取りあえず触ってみての感想です :-)