Last modified: Wed Jun 6 17:29:15 JST 2007
Welcome to pgpool -II page


(last update: 2007/02/12)
[English page]

pgpool-IIとは

pgpool-IIはPostgreSQL専用のミドルウェアで,PostgreSQLのデータベースクラ イアントとPostgreSQLサーバの間に割り込む形で動作し,PostgrSQLに以下のよ うな機能を追加します.

  • 接続数の制限

    PostgreSQLに接続可能なセッション数には限界があり,それを超えて接続するこ とはできません.かと言って,同時セッション数をむやみに多く設定すると,メ モリーなどのリソースが多く消費されてパフォーマンスに影響があります. pgpool-IIでもクライアントからの接続数には上限がありますが,それを超えてもた だちにエラーになることはなく,一定の間待たされるようになっています.した がって,pgpool-IIはPostgreSQLへの接続要求を実質的にキューイングし, PostgreSQLへの過大な接続数を制限することが可能です.

  • コネクションプーリング

    PostgreSQLへの接続を保存しておき,再利用することによってPostgreSQLへの 接続オーバヘッドを低減でき,システム全体のスループットを向上させることが できます.

  • レプリケーション

    pgpool-IIは複数のPostgreSQLサーバを管理することができます.レプリケーション を使用することにより,物理的に2台以上のディスクにリアルタイムでハー ドディスクのバックアップを取ることができ,万が一どれかのディスクに 障害が発生しても運用を継続することができます.

  • 負荷分散

    レプリケーションを運用している場合,すべてのPostgreSQLデータベースの内容 が一致しているので,どのサーバに問い合わせても同じ結果が返ってきます.こ のことを利用して,多数のリクエストをそれぞれのサーバで分担して負荷を軽減 させ,システム全体の性能を向上させることができます.最良の場合にはサーバ 台数に比例した性能向上が見込めます.特に多数のユーザが大量の問い合わせを 投げるような環境で威力を発揮します.

  • パラレルクエリ

    複数のサーバにデータを分割して受け持たせ,それぞれのサーバに同時に検索問 い合わせを投げて,問い合わせの処理時間を短縮するパラレルクエリが利用でき ます.特に大規模なデータを検索するときに威力を発揮します.

pgpool-IIはPostgreSQLバックエンドとフロントエンドの通信プロトコルを理解して その間を中継します.すなわち,PostgreSQLのデータベースアプリケーションか らはPostgreSQLサーバに,PostgreSQLからはデータベースアプリケーションに見 えるように設計されています.そのため,PostgreSQLそのものはもちろん,アプ リケーションの開発言語によらず,PostgreSQLのデータベースアプリケーション にほとんど手を加えることなく,pgpool-IIの機能が利用できます.

pgpool-IIの稼働環境

pgpool-IIは,Linuxをはじめ,SolarisやFreeBSDなどのほとんどのUNIX環境で動作 します.Windowsでは動きません.対応するPostgreSQLのバージョンは, PostgreSQLの6.4以降です.ただしパラレルクエリモードを使用するときは PostgreSQL 7.4以降をお使いください.

pgpool-IIのインストール

pgpool-IIのインストールには,gcc 2.9以上,およびGNU makeが必要です. また,pgpool-IIはlibpqを使用するので,ビルドを行うマシン上にlibpqがインストー ルされていることが必要です.

configureの実行

ソースコードのtar ballを展開したら,configureを実行します.

./configure
configureに指定できるオプションは以下です.
  • --prefix=path pgpool-II本体や関連ファイルをインストールするトップディレクトリを指定します. デフォルトは/usr/localです.
  • --with-pgsql=path PostgreSQLのクライアントライブラリなどがインストールされているトップディ レクトリを指定します.デフォルトはpg_config コマンドで取得できるパスです.

makeの実行

make
make install
でインストールが完了します(GNU makeが必要なので,FreeBSDなどでは makeをgmakeに読み替えてください).

pgpool-IIの設定

pgpool-IIの設定ファイルはデフォルトでは/usr/local/etc/pgpool.confおよび /usr/local/etc/pcp.confです.pgpool-IIは動作モードによって使用できる機能と, 必要な設定項目が異なります.

使用できる機能/モード rawモード コネクションプールモード レプリケーションモード マスタスレーブモード パラレルクエリモード
コネクションプーリング ×
レプリケーション × × × ×
負荷分散 × × ×
縮退運転 × × ×
フェイルオーバ × × ×
パラレルクエリ × × × ×
サーバ台数 1以上 1以上 2以上 2以上 2以上
システムDB 不要 不要 不要 不要 必要

pcp.confの設定

どの動作モードでも,pcp.confの設定は必要です.pgpool-IIには管理者がpgpool-IIの 停止や情報取得などの管理操作を行うためのインターフェイスが用意されていま す.そのインターフェイスを利用するためにはユーザ認証が必要になるので,そ のユーザ名とパスワードをpcp.confに登録します. pgpool-IIをインストールすると,$prefix/etc/pcp.conf.sampleができるので,それを $prefix/etc/pcp.confという名前でコピーします.

cp $prefix/etc/pcp.conf.sample $prefix/etc/pcp.conf
pcp.confでは空白行や#で始まる行はコメントと見なされます. ユーザとパスワードは,
ユーザ名:[md5暗号化したパスワード]
のように指定します. [md5暗号化したパスワード]は,$prefix/bin/pg_md5コマンドで作成できます.
./pg_md5 foo
acbd18db4cc2f85cedef654fccc4a4d8
pcp.confは,pgpool-IIを動作させるユーザIDで読み取り可能になっていなければ なりません.

pgpool.confの設定

前述のように,動作モードによって,pgpool.confの設定項目が異なります. pgpool-IIをインストールすると,$prefix/etc/pgpool.conf.sampleができるので,それを $prefix/etc/pgpool.confという名前でコピーします.

cp $prefix/etc/pgpool.conf.sample $prefix/etc/pgpool.conf
pgpool.confでは空白行や#で始まる行はコメントと見なされます.

rawモード

単にpgpool-IIを経由して接続するだけのモードです.単にPostgreSQLサーバへの接 続セッション数を制限したり,2台以上のPostgreSQLサーバを用意してフェイル オーバ動作をさせたいときに利用します.

listen_addresses

pgpool-IIがTCP/IPコネクションを受け付けるアドレスをホスト名またはIPアドレスで 指定します.「*」を指定するとすべてのIPインタフェースからのコネクショ ンを受け付けます.「''」を指定するとTCP/IPコネクションを受け付けま せん.デフォルト値は「localhost」です. UNIXドメインソケット経由のコネクションは常に受け付けます.

port

pgpool-IIがコネクションを受け付けるポート番号です.デフォルト値は9999です.

socket_dir

pgpool-IIがコネクションを受け付けるUNIXドメインソケットを置くディレクトリです. デフォルト値は'/tmp'ですが,cronにより消されてしまうこともあるので,ほか のディレクトリ,たとえば/var/runなどに置くことをおすすめします.

pcp_port

pcpが使用するポート番号です.

pcp_socket_dir

pcpがコネクションを受け付けるUNIXドメインソケットを置くディレクトリです. デフォルト値は'/tmp'ですが,cronにより消されてしまうこともあるので,ほか のディレクトリ,たとえば/var/runなどに置くことをおすすめします.

backend_socket_dir

UNIXドメインソケット経由でpgpool-IIがPostgreSQLと接続する際に使用する PostgreSQLのUNIXドメインソケットが置かれているディレクトリ.デフォルト値 は/tmpです.

pcp_timeout

pcpがpgppoolと接続する際のタイムアウト値.0にするとタイムアウトしません. デフォルト値は10(秒)です.

num_init_children

preforkするpgpool-IIのサーバプロセスの数です.デフォルト値は32になって います. なお,問い合わせのキャンセルを行うと通常のコネクションとは別に新た なコネクションが張られます.したがって,すべてのコネクションが使用 中の場合は問い合わせのキャンセルができなくってしまうので,ご注意下 さい.問い合わせのキャンセルを必ず保証したい場合は,想定されるコネ クション数の倍の値を設定することをおすすめします.

child_life_time

pgpool-IIの子プロセスの寿命です.アイドル状態になってから child_life_time秒経過すると,一旦終了して新しいプロセスを起動します. メモリーリークその他の障害に備えた予防措置です.child_life_timeのデ フォルト値は300秒,すなわち5分です.0を指定するとこの機能は働きませ ん(すなわち起動しっ放し).なお,まだ一度もコネクションを 受け付けていないプロセスにはchild_life_timeは適用されません.

child_max_connections

各pgpool-II子プロセスへの接続回数がこの設定値を超えると、その子プロセ スを終了します。child_life_timeやconnection_life_timeが効かないくら い忙しいサーバで、PostgreSQLバックエンドが肥大化するのを防ぐのに有 効です。

authentication_timeout

認証処理のタイムアウト時間を秒単位で指定します。0 を指定するとタイ ムアウトを無効にします。authentication_timeout のデフォルト値は 60 です。

logdir

pgpool-IIの各種ログファイルを格納するディレクトリです.現在のところ, pgpool.pidというプロセスIDを格納するファイルだけが作られるようになっ ています.logdirのデフォルト値は'/tmp'です.

print_timestamp

trueならばpgpool-IIのログにタイムスタンプを追加します.デフォルトは trueです.

connection_cache

trueならコネクションをキャッシュします.デフォルトはtrueです.

health_check_timeout

pgpool-IIはサーバ障害やネットワーク障害を検知するために,定期的にバッ クエンドに接続を試みます.これを「ヘルスチェック」と言います.障害 が検知されると,フェイルオーバや縮退運転を試みます. この パラメータは,ネットワークケーブルが抜けた際などにヘルスチェッ クが長時間待たされるのを防ぐためのタイムアウト値を秒単位で指定しま す.デフォルトは20秒です.0を指定するとタイムアウト処理をしません. なお,ヘルスチェックを有効にすると,ヘルスチェックのための余分の接 続が1つ必要になりますので,PostgreSQLのpostgresql.confの設定項目の max_connectionsを少くとも1増やすようにしてください.

health_check_period

ヘルスチェックを行う間隔を秒単位で指定します.0を指定するとヘルス チェックを行いません.デフォルトは0です(つまりヘルスチェックを行い ません).

health_check_user

ヘルスチェックを行うためのPostgreSQLユーザ名です.

ignore_leading_white_space

trueならば、load balanceの際にSQL文行頭の空白を無視します(全角ス ペースは無視されません)。これは、DBI/DBD:Pgのように、勝手に行頭にホ ワイトスペースを追加するようなAPIを使い、ロードバランスしたいときに 有効です。

log_statement

trueならばSQL文をログ出力します.この役目はPostgreSQLの log_statementオプションと似ていて,デバッグオプションがないときでも 問い合わせをログ出力して調べることができるので便利です.

log_hostname

trueならば,psコマンドでの状態表示時にIPアドレスではなく,ホスト名 を表示します.また,log_connectionsが有効な場合にはログにホスト名を 出力します.

log_connections

trueならば、全てのクライアント接続をログへ出力します。

enable_pool_hba

trueならば、pool_hba.confに従ってクライアント認証を行います。 詳細はクライアント認証(HBA)のためのpool_hba.conf設定 方法を参照してください。

backend_hostname

使用するPostgreSQLサーバのホスト名を指定します.空文字を指定するとUNIXド メインソケットで接続します. 実際には,"backend_hostname"の後に0, 1, 2...と数字を付加して使用する複数 のPostgreSQLを区別します.この数字のことを「DBノードID」と呼びます. DBノードID == 0のPostgreSQLは,特別に「マスターDB」と呼ばれます. なお,複数のDBノードを運用している場合,条件によってはマスターDBがダウンしても 運用を続けることができます.この場合は,稼働中かつDBノードIDがもっとも 若いものが新しいマスターDBになります.

1台しかPostgreSQLを使用しない場合は,"backend_hostname0"としてください.

backend_port

使用するPostgreSQLサーバのポート番号を指定します. 実際には,"backend_port"の後に0, 1, 2...とDBノードIDを付加して使用する複数 のPostgreSQLを区別します.1台しかPostgreSQLを使用しない場合は, "backend_port0"としてください.

backend_weight

使用するPostgreSQLサーバに対する負荷分散の比率を指定します. 実際には,"backend_weight"の後にDBノードIDを付加して使用する複数 のPostgreSQLを区別します.1台しかPostgreSQLを使用しない場合は, "backend_weight0"としてください. 負荷分散を使用しない場合は,「1」を設定してください.

rawモードにおけるフェイルオーバ動作について

rawモードにおいて,2台以上のPostgreSQLサーバを指定すると,フェイルオーバ が可能です.フェイルオーバでは,正常時にはbackend_hostname0で指定した PostgreSQLのみを使用し,ほかのサーバにはアクセスしません. backend_hostname0のサーバがダウンすると,次にbackend_hostname1で指定した サーバにアクセスをこころみ,成功すればそれを使用します.以下, backend_hostname2...でも同様になります.

コネクションプールモード

rawモードに加え,コネクションプーリングが利用できるようになります. 設定項目は,rawモードでの設定項目の他に以下を設定します.

max_pool

pgpool-IIの各サーバプロセスがキープするPostgreSQLへの最大コネクション 数です.pgpool-IIは,ユーザ名,データベースが同じならばコネクションを 再利用しますが,そうでなければ新たにPostgreSQLへのコネクションを確 立しようとします.したがって,ここでは想定される[ユーザ名:データベー ス名]のペアの種類の数だけをmax_poolに指定しておく必要があります.も しmax_poolを使いきってしまった場合は一番古いコネクションを切断し, そのスロットが再利用されます. max_poolのデフォルト値は4です. なお,pgpool-II全体としては,num_init_children*max_pool 分だけ PostgreSQLへのコネクションが張られる点に注意してください.

connection_life_time

コネクションプール中のコネクションの有効期間を秒単位で指定します.0 を指定すると有効期間は無限になります.connection_life_timeのデフォ ルト値は0です.

reset_query_list

セッションが終了するときにコネクションを初期化するためのSQLコマンド を「;」で区切って列挙します.デフォルトは以下のようになっていますが, 任意のSQL文を追加しても構いません.

   reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT'
PostgreSQLのバージョンによって使用できるSQLコマンドが違うので, PostgreSQL 7.3以前では注意してください. なお,「ABORT」は,PostgreSQL 7.4以上ではトランザクションブロックの 中にいない場合には発行されません.

コネクションプールモードにおけるフェイルオーバ動作について

rawモードと同様の動作をします.

レプリケーションモード

レプリケーションを有効にするモードです. rawモード,コネクションプールモードに加え,以下を設定します.

replication_mode

レプリケーションモードで動作させる場合はtrueを指定してください.デ フォルト値はfalseです.

replication_strict

このオプションをtrueにすると,マスターDBの問い合わせ処理の完了を待って から次のDBノードの処理に移ります.デッドロックの危険性はなくなりますが, DBノードの間で問い合わせの並列処理を行わなくなるので性能が 低下する場合もあります. このオプションのデフォルト値はtrueです.

replication_timeout

replication_strictがfalseのときにデッドロックを監視するためのタイム アウト時間をミリ秒単位で指定します.デフォルト値は5000,すなわち5秒 です.0を指定するとタイムアウトしなくなります.

load_balance_mode

trueを指定するとレプリケーションモードの際に,SELECT文をマスタとセ カンダリの間でロードバランスします.デフォルト値はfalseです.

replication_stop_on_mismatch

trueを指定するとマスターDBと他のDBノードの間でデータの不一致があった場合 に強制的に縮退運転に入ります.このオプションがfalseの場合は,該当の 問い合わせを強制的に終了するだけに留めます.デフォルト値はfalseです.

replicate_select

true を設定するとロードバランスされない SELECT 文をレプリケーション させます。これは pgpool-II 1.0 までの挙動と同じになります。false を 設定すると SELECT 文をマスタのみに送信します。デフォルト値は false です。

insert_lock

SERIAL型を使っているテーブルをレプリケーションすると,SERIAL型の列 の値がDBノードの間で一致しなくなることがあります.この問題は, 該当テーブルを明示的にロックすることで回避できます(もちろんトランザ クションの並列実行性は犠牲になりますが).しかし,そのためには,

   INSERT INTO ...
   BEGIN;
   LOCK TABLE ...
   INSERT INTO ...
   COMMIT;
に書き換えなければなりません.insert_lockをtrueにすると自動的にトラ ンザクションの開始,テーブルロック,トランザクションの終了を行って くれるので,こうした手間を省くことができます(すでにトランザクショ ンが開始されている場合はLOCK TABLE...だけが実行されます). ただ,このテーブルで本当にSERIAL型が使われているかどうかが判定される わけではないので,SERIAL型を使っていないテーブルでもこうした処理が 行われてしまいます(機能上支障があるわけではないのですが,処理速度 が遅くなってしまいます). この問題を回避するには2つの方法があります.

  1. insert_lockをtrueにして,INSERT文の先頭に/*NO INSERT LOCK*/コメ ントを追加する.このコメントがあると,テーブルロックは行われませ ん.
  2. insert_lockをfalseにして,INSERT文の先頭に/*INSERT LOCK*/コメン トを追加する.このコメントがあると,このINSERT文に対してのみテー ブルロックが行われます.

SERIAL型を使っているテーブルが多い場合は1)を,少ない場合は2)を採用 すると良いでしょう. insert_lockのデフォルト値はfalseです. なお,insert_lockを有効にしてregression testを実行すると,少くとも PostgreSQL 8.0ではtransactions, privileges, rules, alter_tableが failします.ruleでは,viewに対してLOCKをしようとしてしまうこと, ほかのものは

   ! ERROR:  current transaction is aborted, commands ignored until end of transaction block
というようなメッセージが出てしまうためです.たとえば,transactions では,存在しないテーブルに対してINSERTを行うテストが含まれており, pgpoolが最初に存在しないテーブルに対してLOCKを行う結果,エラーになっ てトランザクションがアボート状態になり,続くINSERTで上記エラーが出 てしまいます.

ロードバランスの条件について

load_balance_mode = true を設定した場合,以下の条件を満たした時に問い 合わせはロードバランスされます.

  • PostgreSQLのバージョンが7.4以降
  • 問い合わせが明示的なトランクザションブロックの内側にない(つまり, BEGINを発行していない)
  • SELECT 文(ただし、SELECT nextval と SELECT setval の場合は除く)
  • SELECT INTO 文ではない
  • SELECT FOR UPDATE 文ではない
  • クエリ文字列が SELECT で始まる(ignore_leading_white_space = true の場合は空白は無視します)
上記を満さない場合は SELECT 以外のクエリをバックエンドに送信します。も し SELECT をレプリケーションさせたい場合は、replicate_select = true を 設定するか、
  /*REPLICATION*/ SELECT ...
と、SELECT の前にコメントを付けてください。

レプリケーションモードにおける縮退運転について

PostgreSQLサーバのうち,1台がダウンすると,そのサーバを切り離して縮退運 転に入ります.1台でもサーバが生き残っていれば,システムとしての運用を継 続できます.

マスタースレーブモード

master/slaveモードは,Slony-Iのような,master/slave式のレプリケーショ ンソフトにレプリケーションをまかせるモードです.このモードで使うために は,レプリケーションモードと同じように,DBノードのホスト情報 をセットし,master_slave_modeとload_balance_modeをtrueにします.このと き,問い合わせによってマスターDBだけに問い合わせが送られる場合と,DB ノードの間でロードバランスされて問い合わせが送られる場合があります. ロードバランスの条件はレプリケーションモードと同じです。

マスタースレーブモードでは,pgpool.confのreplication_modeをfalseに,master_slave_mode をtrueにします.

パラレルモード

パラレルクエリ機能が利用できるモードです.レプリケーションや負荷分散機能 は利用できません.

システムDBの設定

パラレルモードを利用するためには,システムDBを設定する必要があります. システムDBはデータを各PostgreSQLサーバで分割するためのルールを PostgreSQLのテーブルの形で保持します.システムDBはpgpoolが動作するホスト と同じホストに置く必要はありません.システムDBの設定はpgpool.confで行い ます.

system_db_hostname

システムDBが動いているホスト名です.空文字を指定すると,UNIXドメインソケッ トで接続します.

system_db_port

システムDBのポート番号です.

system_dbname

システムDBは専用のデータベースに設置します.そのデータベース名を指定します. このデータベースはあらかじめ存在しなければなりません.ここでは, "pgpool"というデータベース名にするものとします.

system_db_schema

システムDBは専用のスキーマに設置します.そのスキーマ名を指定します. このスキーマはあらかじめ存在しなければなりません.ここでは, "pgpool_catalog"というスキーマにするものとします.

system_db_user

システムDBに接続するときのユーザ名です. 

system_db_password

システムDBに接続するときのパスワードです.パスワードを設定していない場合 は空文字にしておきます.

システムDBの初期設定

システムDBにスキーマとテーブルを作成します.初期設定用のスクリプトが $prefix/share/system_db.sqlにあるのでそれを利用します.ただし,このスク リプトではスキーマ名が"pgpool_catalog"となっているので,違うスキーマを使 う場合は適当に書き換えてください.また,データベース名として"pgpool"以外 を使う場合は以下を適当に読み替えてください.

psql -f $prefix/share/system_db.sql pgpool

dblinkのインストール

パラレルモードではdblinkを使います。dblinkはPostgreSQLソースファイル ($POSTGRES_SRC)
$(POSTGRES_SRC)/contrib/dblink

にあります。$POSTGRES_SRC/contrib/dblink/README.dblinkを参考にシステム DBにdblinkをインストールしてください。

また、pgpoolデータベースに関数の登録が必要です。
psql pgpool < $POSTGRES_SRC/contrib/dblink/dblink.sql

コネクション数の設定

パラレルモードでは、クエリによりシステムDBからdblink経由でpgpoolに接続 するので、想定される同時接続数以上のコネクションが必要になる場合があり ます。そのため、pgpool.confのnum_init_childrenには同時接続数より十分大 きい値を設定して下さい。

目安として以下の式でnum_init_childrenを設定してください。

num_init_children = 想定される同時接続数 * ( 1 + クエリの中で使われているテーブルの最大数)

データ分割ルールの登録

パラレルクエリの対象となるテーブルのデータ分割ルールはあらかじめ pgpool_catalog.dist_def というテーブルに登録しておきます.

CREATE TABLE pgpool_catalog.dist_def(
	dbname TEXT,	-- DB名
	schema_name TEXT,	--schema名
	table_name TEXT,	-- テーブル名
	col_name TEXT NOT NULL CHECK (col_name = ANY (col_list)),	-- 分散キー列名
	col_list TEXT[] NOT NULL,	-- tableの属性名
	type_list TEXT[] NOT NULL,	-- 属性のタイプ名
	dist_def_func TEXT NOT NULL,	-- 分散先のDBノードを決定する関数名
	PRIMARY KEY (dbname,schema_name,table_name)
);
pgbenchのテーブルを分割するルールの例を示します.
INSERT INTO pgpool_catalog.dist_def VALUES (
	'pgpool',
	'public',
	'accounts',
	'aid',
	ARRAY['aid','bid','abalance','filler'],
	ARRAY['integer','integer','integer','character(84)'],
	'pgpool_catalog.dist_def_accounts'
);

INSERT INTO pgpool_catalog.dist_def VALUES (
	'pgpool',
	'public',
	'branches',
	'bid',
	ARRAY['bid','bbalance','filler'],
	ARRAY['integer','integer','character(84)'],
	'pgpool_catalog.dist_def_branches'
);
INSERT INTO pgpool_catalog.dist_def VALUES (
	'pgpool',
	'public',
	'tellers',
	'tid',
	ARRAY['tid','bid','tbalance','filler'],
	ARRAY['integer','integer','integer','character(84)'],
	'pgpool_catalog.dist_def_tellers'
);

ここで,pgpool_catalog.dist_def_accounts, pgpool_catalog.dist_def_branches,pgpool_catalog.dist_def_tellersは,引 数として分割キーの値を受け取り,どのPostgreSQLサーバ(「DBノード」と呼び ます)を0からの番号で返す関数です.ここでは,3台のDBノードにデータを分割 する関数の例を示します.

CREATE OR REPLACE FUNCTION pgpool_catalog.dist_def_accounts (val ANYELEMENT) RETURNS INTEGER AS '
  SELECT CASE WHEN $1 >= 1 and $1 <= 30000 THEN 0
	      WHEN $1 > 30000 and $1 <= 60000 THEN 1
	      ELSE 2
  END' LANGUAGE SQL;
 
CREATE OR REPLACE FUNCTION pgpool_catalog.dist_def_branches (val ANYELEMENT) RETURNS INTEGER AS '
  SELECT 0
  ' LANGUAGE SQL;
	 
CREATE OR REPLACE FUNCTION pgpool_catalog.dist_def_tellers (val ANYELEMENT) RETURNS INTEGER AS '
  SELECT CASE WHEN $1 >= 1 and $1 <= 3 THEN 0
          WHEN $1 > 3 and $1 <= 6 THEN 1
	  ELSE 2
  END' LANGUAGE SQL;

クライアント認証(HBA)のための pool_hba.conf 設定方法

PostgreSQLのpg_hba.confと同じようにpgpoolでもpool_config.confファイ ルを使ったクライアント認証がサポートされています。

pgpoolをインストールするとデフォルトインストール先の設定ファイルディ レクトリ"/usr/local/etc"にpool_hba.conf.sampleが一緒にインストール されます。このpool_hba.conf.sampleファイルをpool_hba.confとしてコピー し、必要であれば編集してください。デフォルトではpool_hbaによる認証は有 効になっています。

pool_hba.confのフォーマットはpg_hba.confのものとほとんど同じです。

     local      DATABASE  USER  METHOD  [OPTION]
     host       DATABASE  USER  CIDR-ADDRESS  METHOD  [OPTION]

各フィールドで設定できる値の詳細は"pool_hba.conf.sample"を参照して ください。

以下はpool_hbaの制限事項です。

  • "hostssl"接続タイプはサポートされません
  • 現在pgpoolはSSL接続をサポートしていないので"hostssl"は指定するこ とができません。

  • DATABASEフィールド値として"samegroup"はサポートされません
  • pgpoolはバックエンドサーバにあるユーザ情報を事前に知る事ができな いため、データベース名はpool_hba.confにある値のみと比較されます。 なのでグループに関する認証はpool_hbaで行うことができません。

  • USERフィールド値として"+"を使ったグループ指定はサポートされません
  • 上記の"samegroup"と同じ理由で、ユーザ名はpool_hba.confにある値の みと比較されます。グループに関する認証はpool_hbaで行うことはでき ません。

  • IPv6アドレス/マスク表記法はサポートされません
  • 現在pgpoolはIPv6をサポートしていません。

  • "trust", "reject", "pam"以外のメソッドはサポートされません
  • これも上記の"samegroup"と同じ理由によるものです。pgpoolはバックエ ンドのユーザ/パスワード情報を持っていないので、バックエンドに保存 されているパスワードを使った認証を行うことができません。

ここで説明された機能、制限はクライアントとpgpool間で行われるクライ アント認証についてだということに注意してください。クラインアントは pgpoolのクライアント認証に成功したとしても、PostgreSQLによるクライ アント認証に成功しないと接続状態となりません。pool_hbaにとってはク ライアントに指定されたユーザ名やデータベース名 (例. psql -U testuser testdb)が実際にバックエンド上に存在するかどう かは問題ではありません。それがpool_hba.confの値とマッチするかどうか でチェックが行われます。

pgpoolが稼働するホスト上のユーザ情報を使ったPAM認証を利用することが できます。pgpoolをPAMサポート付きでビルドするにはconfigureオプショ ンに"--with-pam"を指定してください。

     ./configure --with-pam

実際にPAM認証を有効にするには、pool_hba.confで"pam"メソッドを設定す るのに加え、pgpoolのサービス設定ファイルをシステムのPAM設定ディレクト リ(通常は /etc/pam.d に作成する必要があります。サービス設定ファイ ルの例はインストールディレクトリの"share/pgpool.pam"を参考にしてく ださい。

pgpool-IIの起動と停止

以上で設定が終わったので,各DBノードを起動し,必要ならばシステムDBも起動 してからpgpool-IIを起動します.

pgpool [-c][-f config_file][-a hba_file][-F pcp_config_file][-n][-d]
-cクエリキャッシュを消去します
-f config_filepgpool-IIの設定ファイルを指定します
-a hba_fileHBA認証設定ファイルを指定します
-F pcp_config_filepcpの設定ファイルを指定します
-nデーモンモードで起動しません(制御端末を切り離しません
-dデバッグモードで起動します
pgpool-IIの停止は後述のpcpコマンドでもできますが,pgpool-IIコマンドを使うこと もできます.
pgpool [-f config_file][-F pcp_config_file] [-m {s[mart]|f[ast]|i[mmediate]}] stop
-m s[mart]接続中のクライアントが接続を終わるのを待ってから停止します(デフォルト)
-m f[ast]接続中のクライアントが接続を終わるのを待たずに直ちに停止します
-m i[mmediate]-m fと同じ動作です

制限事項

認証・アクセス制御方式

  • レプリケーションモードまたマスタ/スレーブモード時にはtrust, reject, clear text password, pam, 認証方式だけが利用できます.md5認証,crypt認証などの認証方式は利用できません.
  • それ以外のモードでは,trust, reject, clear text password, pam, crypt, md5認証方式だけが利用できます.
  • pgpool-II自体にpg_hba.confによるアクセス制限はかかりません. TCP/IPコネクションを許可している場合,pgpool-II自体にはどのホストか らでも接続できてしまいます.必要ならばiptablesなどを使ってアク セス制限をかけて下さい(もちろん,pgpool-IIが接続するPostgreSQLサー バではpg_hba.confによるアクセス制限が有効です).

レプリケーションモードで注意が必要な関数など

pgpool-IIでは同じ問い合わせを送っても異なる結 果を返すようなデータ,たとえば乱数やトランザクションID,OID,SERIAL, シーケンス,CURRENT_TIMETSTAMPのようなものに関してはレプリケーショ ンはしますが,2台のホストでまったく同じ値がコピーされる保証はありま せん.

CREATE TEMP TABLEで作成されたテーブルはフロントエンドがセッショ ンを終了しても削除されません.これは,コネクションプールの効 果でバックエンドから見るとセッションが継続しているように見え るからです.セッションの終了時に明示的にDROP TABLEするか,ト ランザクションブロックの中でCREATE TEMP TABLE ... ON COMMIT DROPをお使い下さい.

クエリについて

pgpool-II では扱うことができないクエリについて説明します。

マルチバイト文字について

制限対象:全モード

現在の実装では、マルチバイト文字の変換処理を行いません。クライアントエ ンコーディング、バックエンドノードのサーバエンコーディング、システム DB のサーバエンコーディングを一致させるようにしてください。

拡張問い合わせプロトコル

制限対象:パラレルモード

JDBC ドライバなどのような拡張問い合わせプロトコルには対応していません。 必ず簡易問い合わせプロトコルを使用してください。

INSERT

制限対象:パラレルモード

INSERT を行う際には、分割ルールとなる値を DEFAULT にはできません。例え ばテーブル t に x というカラムがあり、x が分割ルールの対象カラムだった 場合には、

  INSERT INTO t(x) VALUES (DEFAULT);
はできません。また、分割ルールとなる値が関数呼び出しの場合も 対応していません。
  INSERT INTO t(x) VALUES (func());
必ず明示的に値を与える必要があります。 また、SELECT INTO や INSERT INTO ... SELECT という形式もサポートしてい ません。

UPDATE

制限対象:パラレルモード

分割ルールとなるカラムを更新すると分割ルールに従ったデータの整合性が崩 れる可能性があります。pgpool-II では特にデータの再配置ということは行い ません。

もし制約違反などにより一部のノードでエラーになった場合にロールバックす ることはできません。

WHERE 句にサブクエリや関数呼び出しがある場合には正しく動かない可能性が あります。

例:UPDATE branches set bid = 100 where bid = (select max(bid) from beances);

SELECT ... FOR UPDATE

制限対象:パラレルモード

WHERE 句にサブクエリや関数呼び出しがある場合には正しく動かない可能性が あります。

例:SELECT * FROM  branches where bid = (select max(bid) from beances) FOR UPDATE;

COPY

制限対象:パラレルモード

COPY BINARY には対応していません。また、ファイルからのコピーにも対応し ていません。COPY FROM STDIN と COPY TO STDOUT のみ対応しています。

ALTER/CREATE TABLE について

制限対象:パラレルモード

pgpool に情報を更新させるためには、pgpool を再起動する必要があります。

トランザクション

制限対象:パラレルモード

トランザクション中に発行される SELECT は dblink を経由する場合には別ト ランザクションになります。以下に例を示します。

  BEGIN;
  INSERT INTO t(a) VALUES (1);
  SELECT * FROM t ORDER BY a; <-- 上の INSERT した値は見えない
  END;

また制約違反などにより一部のノードでエラーになった場合にロールバックすることはできません。

View/Rule

制限対象:パラレルモード

View や Rule は各ノードに同じ内容が定義されます。

  SELECT * FROM a, b where a.i = b.i
のような JOIN の場合に、a と b はノード内でのみ処理を行い、その結果を 統合します。ノードをまたがった JOIN を行う View を作成することはできま せん。Rule についても同様になります。

関数/トリガについて

制限対象:パラレルモード

関数は各ノードに同じ内容が定義されます。関数内で JOIN や他のノードのデー タ操作を行うことはできません。

デッドロックについて

制限対象:パラレルモード

ノード間をまたがるデッドロックを検出することができません。

例:tellersテーブルは以下のルールで分割されている。
    tid <= 10 ノード 0
    tid >= 10 ノード 1

  A) BEGIN;
  B) BEGIN;
  A) SELECT * FROM tellers WHERE tid = 11 FOR UPDATE;
  B) SELECT * FROM tellers WHERE tid = 1 FOR UPDATE;
  A) SELECT * FROM tellers WHERE tid = 1 FOR UPDATE;
  B) SELECT * FROM tellers WHERE tid = 11 FOR UPDATE;
この場合、単一のノードではデッドロックを検知できないため、pgpool は待 たされた状態になります。この現象は SELECT FOR UPDATE 以外にも行ロック を獲得するクエリで発生する可能性があります。回避策としましては、 replication_timeout を設定するようにしてください。

また、あるノードでデッドロックが発生した場合は、各ノードのトランザクショ ンの状態が異なる状況になります。そのため、デッドロックを検知した時点で 以下のログを出力して pgpool は該当のプロセスを終了させます。

  pool_read_kind: kind does not match between master(84) slot[1] (69)

スキーマについて

制限対象:パラレルモード

public 以外のスキーマに属すようなオブジェクトの参照は必ず

  スキーマ.オブジェクト
と指定するようにしてください。
  set search_path = xxx
を指定し、スキーマ名を省略すると、pgpool がどの分散ルールを適用するか 判断できません。

システム DB

分割ルール

pgpool-II では分割ルールの対象のカラムは 1 つのみとします。x と y の OR 条件などといったものには対応していません。

ビルドに必要な環境

libpq

pgpool-II では libpq をリンクします。libpq のバージョンは 2.0 の場合、 configure に失敗します。必ず libpq 3.0 (PostgreSQL 7.4) をリンクするよ うにしてください。また、SystemDB のバージョンも PostgreSQL 7.4 以降が 必須になります。

クエリキャッシュ

現在のクエリキャッシュの実装では、キャッシュの無効化を手動で行う必要が あります。

pgpool との互換性

pgpool の場合 /*STRICT*/ など、pgpool を制御する特殊なコメントを書ける ようになっていました。pgpool-II の現在の実装では特殊コメントを無視しま す。

リファレンス

PCPコマンドリファレンス

PCPコマンド一覧

pgpool-IIを操作するUNIXコマンドとして、以下のものがあります。

   * pcp_node_count	- ノード数を取得する
   * pcp_node_info	- ノード情報を取得する
   * pcp_proc_count	- プロセス一覧を取得する
   * pcp_proc_info	- プロセス情報を取得する
   * pcp_systemdb_info	- システムDB情報を取得する
   * pcp_detach_node	- ノードを切り離す
   * pcp_attach_node	- ノードを復帰させる
   * pcp_stop_pgpool	- pgpool-IIを停止させる

共通引数

全てのコマンドには共通する引数があります。これは接続するpgpool-IIの情報や認証 情報などです。

   ex)
   $ pcp_node_count 10 localhost 9898 postgres hogehoge

    第一引数    - タイムアウト値
		秒数でタイムアウト値を指定します。この時間内にpgpool-IIから応
		答がない場合はコネクションを切断して終了します。
    第二引数	- pgpool-IIが稼動しているホスト名
    第三引数	- pgpool-IIが受け付けているポート番号
    第四引数	- PCPユーザ名
    第五引数	- PCPパスワード

PCPユーザ名とパスワードは ./configure 時に --prefix で指定した 'インストールディレクトリ/etc' にある pcp.conf 内に記述されているものを指定 します。pcp.conf ファイルの場所がデフォルト以外の場所にある場合、pgpool の -F オプションでその位置を指定することができます。 パスワードはコマンドに渡す時点でmd5化されている必要はありません。

コマンド