[PHP-users 12571] session_pgsql 0.4.1

Yasuo Ohgaki php-users@php.gr.jp
Thu, 16 Jan 2003 17:39:40 +0900


大垣です。

PostgreSQLも7.3になってかなりsesion 管理ような用途に
向くようになったのではと思っています。久しぶりに、
PostgreSQLをセッションデータ保存用に使うセーブハンドラ
モジュールを更新しました。実装しようと考えていたほとんど
の機能を追加しました。

http://sourceforge.net/projects/phpform-ext/

主な機能
 - PostgreSQL DBの自動負荷分散
 - PostgreSQL DB障害時の自動切替え
 - 共有メモリを使ったより効率的なガーベッジコレクション
 - テーブルの自動作成
 - エラー回数/アクセス回数等の記録
 - スクリプトから設定できるユーザー定義フィールド
   (他のPostgreSQLテーブルとのJOIN用)

特徴
 - スクリプト版よりかなり高速(2倍以上)
 - ほとんどの自分で設定しなくても利用可
   (特にWeb/DBを1台で済ませている場合)
 - Windowsでは使えません
 - PHP 4.3.0以上が必要
 - VACUUM/REINDEXも自動
 - 障害時のセッションDBの自動切替えをサポートしているので
   セッションDBに不具合が起きても、最低限サービスは継続で
   きる。
 - ユーザーがスクリプトから自由に設定できるフィールドがあ
   るので、PostgreSQLの他のテーブルとクエリーができて便利
   (現在ログインしているユーザーを名前付きで一覧するなど)

基本的な使い方は比較的簡単です。PostgreSQLとPHPを
session_pgsql付き(--with-session-pgsql)で
ローカルマシンにインストールします。

コンパイルにはlibpqとヘッダ、libmmとヘッダが必要です。
RPMならpostgresql-libs-<version>.rpm, mm-<version>.rpm
とmm-devel-<version>.rpmが必要です。
 tarアーカイブを展開して作成されるsession_pgsqlをext/に
コピーして、php-4.3.0のソースのルートから

% ./buildconf
% ./configure --with-apxs --with-session-pgsql <other options>
% make
% make install

でApacheならインストールできます。
buildconfの実行にはいくつかツールが必要です。インストール
されていない場合はオンラインマニュアルを参照してください。
(phpizeでモジュール単独のビルドもできるはずですが、試してい
ません。ビルドできなかったら教えてください。)

次にsession_pgsqlが利用するユーザーとデータベースを作成し
ます。PostgreSQLのスーパーユーザー(普通はpostgres)で

% createuser nobody
% createdb php_session

として、ユーザーとDBを作ります。
php.iniに
session.save_handler = pgsql
とするか、スクリプトからセッション開始前に
session_module_name('pgsql');
を記述します。
httpdを再起動すると、session_pgsqlは
session_pgsql.db php.ini設定を参照し
(デフォルト: host=localhost user=nobody dbname=php_session)
セッション保存用のテーブルが必要な場合は作成します。

# セキュリティーを考えて設定は適切に変更してください。

session_pgsql.dbに";"区切りで複数のデータベースサーバ
を指定すると自動的に負荷分散してくれます。Session ID
を基準に負荷分散しているので、複数のWebサーバがあって
も構いません。複数のWebサーバーから利用する場合は必ず
同じsession_pgsql.db設定を利用します。

複数DBサーバーのphp.ini設定例:
session_pgsql.dbhost="db1 user=web dbname=php_session; host=db2 user=web dbname=php_session"

デフォルトでは最大31までのセッションDBを指定できます。
かなり大規模なWebサイトでも31台以上のDBサーバーを使っ
て負荷分散を行なう必要は無いと思います。

注意点:
 - セッションデータの保存にはTEXTフィールドを使っています。
   バイナリやクライアントエンコーディング以外の文字を$_SESSION
   に保存するとトランザクションがアボートしてセッション情報が
   保存されません。(PostgreSQL 7.2以上の場合)
 - 古いPostgreSQL (確か7.0以下)の場合、最大レコード長がブロッ
   クサイズに制限されます。(約8KB)7.1以上の場合はセッションデー
   タは1GBまで保存できます。
 - 複数のWebサーバーから利用する場合、VACUUMやガーベッジコレク
   ションはcronなどから実行した方が良いです。
 - いいかげんに書いたREADME(英語)にはもう少し説明がありますが、
   関数に関する説明はまだ書けていません。以下はソースからの関数
   プロトタイプの抜粋です。

/* {{{ proto array session_pgsql_status(void)
   Returns current pgsql save handler status */
/* {{{ proto bool session_pgsql_reset(void)
   Reset connection to session database servsers */
/* {{{ proto array session_pgsql_info(void)
   Returns current session info */
/* {{{ proto bool session_pgsql_set_field(string value)
   Set custom field value */
/* {{{ proto string session_pgsql_get_field(void)
   Get custom field value */
/* {{{ proto bool session_pgsql_add_error(int error_level [, string error_message])
   Increments error counts and sets last error message */
/* {{{ proto array session_pgsql_get_error([bool with_error_message])
   Returns number of errors and last error message */

TODO:
 - ショートサーキット(セッション配列が変更されていない場合に
   DBレコードを更新しない)オプションの追加。善し悪しあります
   が、このオプションを追加するとかなりの高速化が期待できます。

まだあまりテストをしていないので、私は問題を見つけていませ
んが、普通に使う分には特に問題はないと思います。

問題を見つけ場合は気軽にレポートしてください。
# 直メールで結構です。

--
Yasuo Ohgaki