Welcome to pgpool -II page |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(last update: 2007/02/12) [English page] |
pgpool-IIとはpgpool-IIはPostgreSQL専用のミドルウェアで,PostgreSQLのデータベースクラ イアントとPostgreSQLサーバの間に割り込む形で動作し,PostgrSQLに以下のよ うな機能を追加します.
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がインストー ルされていることが必要です.
pgpool-IIの設定pgpool-IIの設定ファイルはデフォルトでは/usr/local/etc/pgpool.confおよび /usr/local/etc/pcp.confです.pgpool-IIは動作モードによって使用できる機能と, 必要な設定項目が異なります.
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.confpcp.confでは空白行や#で始まる行はコメントと見なされます. ユーザとパスワードは, ユーザ名:[md5暗号化したパスワード]のように指定します. [md5暗号化したパスワード]は,$prefix/bin/pg_md5コマンドで作成できます. ./pg_md5 foo acbd18db4cc2f85cedef654fccc4a4d8pcp.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.confpgpool.confでは空白行や#で始まる行はコメントと見なされます. rawモード単にpgpool-IIを経由して接続するだけのモードです.単にPostgreSQLサーバへの接 続セッション数を制限したり,2台以上のPostgreSQLサーバを用意してフェイル オーバ動作をさせたいときに利用します.
rawモードにおけるフェイルオーバ動作についてrawモードにおいて,2台以上のPostgreSQLサーバを指定すると,フェイルオーバ が可能です.フェイルオーバでは,正常時にはbackend_hostname0で指定した PostgreSQLのみを使用し,ほかのサーバにはアクセスしません. backend_hostname0のサーバがダウンすると,次にbackend_hostname1で指定した サーバにアクセスをこころみ,成功すればそれを使用します.以下, backend_hostname2...でも同様になります. コネクションプールモードrawモードに加え,コネクションプーリングが利用できるようになります. 設定項目は,rawモードでの設定項目の他に以下を設定します.
コネクションプールモードにおけるフェイルオーバ動作についてrawモードと同様の動作をします. レプリケーションモードレプリケーションを有効にするモードです. rawモード,コネクションプールモードに加え,以下を設定します.
ロードバランスの条件についてload_balance_mode = 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で行い ます.
システム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の制限事項です。
現在pgpoolはSSL接続をサポートしていないので"hostssl"は指定するこ とができません。 pgpoolはバックエンドサーバにあるユーザ情報を事前に知る事ができな いため、データベース名はpool_hba.confにある値のみと比較されます。 なのでグループに関する認証はpool_hbaで行うことができません。 上記の"samegroup"と同じ理由で、ユーザ名はpool_hba.confにある値の みと比較されます。グループに関する認証はpool_hbaで行うことはでき ません。 現在pgpoolはIPv6をサポートしていません。 これも上記の"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]
pgpool [-f config_file][-F pcp_config_file] [-m {s[mart]|f[ast]|i[mmediate]}] stop
制限事項
認証・アクセス制御方式
レプリケーションモードで注意が必要な関数など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 条件などといったものには対応していません。 ビルドに必要な環境libpqpgpool-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化されている必要はありません。 コマンド群全てのコマンドは、実行した結果が標準出力に表示されます。 pcp_node_count
書式: pcp_node_count _timeout_ _host_ _port_ _userid_ _passwd_pgpool-IIの pgpool.conf で定義されたノードの総数を表示します。切り離されている ノードの区別はしません。 pcp_node_info
書式: pcp_node_info _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_pgpool-IIの pgpool.conf で定義されたノードの情報を表示します。出力結果は以下の 例の通りです。 ex) $ pcp_node_info 10 localhost 9898 postgres hogehoge 0 host1 5432 1 1073741823.500000 結果は以下の順の通りです。 1. ノードのホスト名 2. ノードのポート番号 3. ステータス 4. ロードバランスウェイト ステータスは[0..3]までの数字で表わされます。各数字の意味は: 0 - 初期化時のみに表われる。PCPコマンドで表示されることはない。 1 - ノード稼働中。接続無し 2 - ノード稼働中。接続有り 3 - ノードダウンロードバランスウェイトはNormalizeされたフォーマットで出力されます。 定義されていないノードIDを指定するとBackendErrorと表示され、終了コード12で終 了します。 pcp_proc_count
書式: pcp_proc_count _timeout_ _host_ _port_ _userid_ _passwd_pgpool-IIの子プロセスのプロセスIDを一覧表示します。複数ある場合は空白文字で区 切られます。 pcp_proc_info
書式: pcp_proc_info _timeout_ _host_ _port_ _userid_ _passwd_ _processid_pgpool-IIの子プロセス情報を表示します。出力結果は以下の例の通りです。 ex) $ pcp_proc_info 10 localhost 9898 postgres hogehoge 3815 postgres_db postgres 1150769932 1150767351 3 0 1 結果は以下の順の通りです。 1. 接続しているデータベース名 2. 接続しているユーザ名 3. プロセススタート時刻 4. コネクション作成時刻 5. プロトコルメジャーバージョン 6. プロトコルマイナーバージョン 7. コネクション使用回数 コネクションがバックエンドに対して張られていない場合、データは表示されません。 コネクション情報が複数ある場合、複数行に1行1コネクション情報で表示されます。 時刻はEPOCHタイムからの秒数で表わされます。 定義されていないプロセスIDを指定するとBackendErrorと表示され、終了コード12で 終了します。 pcp_systemdb_info
書式: pcp_systemdb_info _timeout_ _host_ _port_ _userid_ _passwd_ pgpool-IIのシステムDB情報を表示します。出力結果は以下の通りです。 $ pcp_systemdb_info 10 localhost 9898 postgres hogehoge localhost 5432 yamaguti '' pgpool_catalog pgpool 3 yamaguti public accounts aid 4 aid bid abalance filler integer integer integer character(84) dist_def_accounts yamaguti public branches bid 3 bid bbalance filler integer integer character(84) dist_def_branches yamaguti public tellers bid 4 tid bid tbalance filler integer integer integer character(84) dist_def_tellers まず一行目にシステムDBの情報が表示されます。結果は以下の順の通りです。 1. ホスト名 2. ポート番号 3. ユーザ名 4. パスワード。空の場合は''で表示されます。 5. スキーマ名 6. データベース名 7. 分散定義関数の数 二行目以降は分散定義が表示されます。複数の定義がある場合は、一つの定義につき 一行表示されます。結果は以下の順の通りです。 1. 分散対象のデータベース名 2. 分散対象のスキーマ名 3. 分散対象のテーブル名 4. 分散キーカラム名 5. 分散対象テーブル中のカラム数 6. カラム名リスト(5.のカラム数分表示されます) 7. カラム型リスト(5.のカラム数分表示されます) 8. 分散定義関数名 システムDBが定義されていない(pgpool-IIモードでない、かつクエリキャッシュがオ フの)場合に実行すると、BackendErrorと表示され、終了コード12で終了します。 pcp_detach_node
書式: pcp_detach_node _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_ pgpool-IIのノードを切り離します。 pcp_attach_node
書式: pcp_attach_node _timeout_ _host_ _port_ _userid_ _passwd_ _nodeid_ pgpool-IIのノードを復帰させます。 pcp_stop_pgpool
書式: pcp_stop_pgpool _timeout_ _host_ _port_ _userid_ _passwd_ _mode_ pgpool-IIを指定されたモードでシャットダウンします。指定できるモードは以下の通 りです。 s - smart モード f - fast モード i - immediate モード pgpool-IIが起動していない場合はConnectionErrorと表示され、終了コード8で終了し ます。 ※ 現在は fast モードと immediate シャットダウンの処理に区別はあり ません。命令を送った時点でクライアントがいる・いないに関わらず シャットダウン処理を即座に行います。 終了ステータスPCPコマンドは正常に処理を終了した場合、ステータス'0'で終了します。エラーが起 きた場合は以下のステータスにより終了します。 UNKNOWNERR 1 不明なエラー EOFERR 2 EOFエラー NOMEMERR 3 メモリ不足 READERR 4 サーバからのデータ読み込みエラー WRITEERR 5 サーバへのデータ書き込みエラー TIMEOUTERR 6 タイムアウト INVALERR 7 PCPコマンドへの不正なオプション CONNERR 8 サーバ接続エラー NOCONNERR 9 接続が存在しない SOCKERR 10 ソケットエラー HOSTERR 11 ホスト名解決エラー BACKENDERR 12 サーバでのPCP処理エラー。存在しないプロセスIDの情報を取 得しようとした場合など AUTHERR 13 認証エラー 内部情報パラレル実行エンジンpgpool-IIにはパラレル実行エンジンが組み込まれています。 このエンジンは、パラレルモードのときに、各ノードに同じクエリを問い合 わせ、ノードの応答順に結果をフロントエンドに送信するエンジンのことを 指します。 クエリ書き換えパラレルモードでpgpool-IIが行うクエリ書き換えについて説明します。 はじめにパラレルモードでは、クライアントが送信した検索系の問い合わせは、SQL パーサを通してからシステムDBに登録されている情報をもとに解析を行い、 クエリを以下の4つのタイプに分類します。
以下では、上記の4つのパターンについて説明します。 クエリ書き換えが必要ないクエリクエリ書き換えが必要ないクエリは、パラレル実行エンジンを使って各ノ ードにクエリを問い合わせます。 このタイプのクエリは、以下の条件をすべて満たす必要があります。
例) SELECT * FROM t1 WHERE t1.a = 100 pgpool-II独自のキーワードを持ったクエリpgpool-ll独自のキーワードを持ったクエリは以下のクエリです。 select pool_parallel('クエリ')pgpoolはこのクエリを受け取ると、pool_parallel関数の引数の中のクエリ を、パラレル実行エンジンを使って各ノードに問い合わせます。 なお、このクエリはシステムDBのdblink経由から送信されるクエリで、一般ユーザ が使うことを想定していません。 クエリの書き換えが必要なクエリ上記2つのタイプのクエリと例外的なクエリを除いて、検索系のクエリは書き 換えを行います。 pgpool-IIでのクエリ書き換えは、各ノードに分散しているテーブルを一つ にまとめ、ユーザが参照したいテーブルを作成します。 たとえばt1というテーブルがある場合には、 t1 = dblink('host','select pool_parallel(\'select * from t1\')') as t1 (colname type, ...)と書き換えます。 ここで、dblinkは第一引数のホストに第二引数のクエリを実行し、クエリの 結果を受け取る関数です。 また、dblinkの中のpool_parallel関数はpgpool-II独自のキーワードを もったクエリなので、このクエリを受け取ったpgpool-IIは、パラレル実行 エンジンを使って、各ノードに問い合わせを行います。これにより、各ノー ドに分散しているテーブルを一つにまとめることができます。 たとえば、 SELECT * FROM t1 ORDER BY a; というクエリは、 SELECT * FROM dblink('host','pool_parallel(\'SELECT * FROM t1\') as t1 (colname type, ...a) ORDER BY a; と書き換えられます。 上記のとおり書き換えられたクエリはシステムDBに送られ、pgpoolを経由してフ ロントエンドに問い合わせ結果を送信します。 しかし、このままでは各ノードのテーブルをシステムDBに送信し、システムD Bにテーブルデータがそろったたあとにソートなどの処理を行うので、システ ムDBがボトルネックとなってしまいます。そこでpgpool-IIでは特定のクエリ に対しては、以下のような特別な処理を行います。
なお、この処理はサブクエリに対しても条件を満たせば行われます。 次にこの処理について説明します。 WHERE句による条件の絞り込みたとえば、 SELECT * FROM t1 WHERE a = 100 ORDER BY a;というクエリは、以下のようにWHERE 句をdblinkの中に入れることが可能です。 SELECT * FROM dblink('host','pool_parallel(\'SELECT * FROM t1 WHERE a = 100 \') as t1 (colname type, ...a) ORDER BY a;dblinkの中にWHERE 句をいれることにより、検索条件の絞り込みを各ノードに 行わせ、システムDBの負荷を下げることができます。 上記の書き換えが行われるためには、以下の条件をすべて満たす必要がありま す。
たとえば、 SELECT * FROM t1 WHERE a = 100 and b > (サブクエリ);というクエリは、以下のようにクエリを書き換えます。 SELECT * FROM dblink('host','pool_parallel(\'SELECT * FROM t1 WHERE a = 100 and TRUE\') as t1 (colname type, ...) WHERE a = 100 and b > (サブクエリ); (*)ここで外側のWHERE 句の a = 100 は、構文上、無意味なものとなります が、現状のpgpool-IIでは、 a = 100 をなくすことを行いません。また、テーブルの結合を行うクエリ SELECT * FROM t1,t2 WHERE t1.a = 100 and t2.a = 200;は、以下のようにクエリを書き換えます。 SELECT * FROM dblink('host','pool_parallel(\'SELECT * FROM t1 WHERE t1.a = 100 and TRUE\') as t1 (colname type, ...), dblink('host','pool_parallel(\'SELECT * FROM t2 WHERE TRUE and t2.a = 200\') as t2 (colname type, ...) WHERE t1.a = 100 and t2.a = 200;ここでも、テーブルごとに検索条件をチェックし、可能な限りpool_parallel関数のなか にWHERE 句を入れて並列処理を行います。 集約によるクエリ書き換え集計を行うクエリ(集約関数、GROUP BY )は各ノードに計算させ、システムDBで 再集計を行うことにより、システムDBの負荷を減らしパフォーマンスも向上 します。 まず、最初にpgpool-IIが実際に行うクエリの書き換えを見てみます。 count(*) を使ったクエリは、以下のように書き換えが行われます。 select count(*) from t1; -> クエリ書き換え SELECT sum(arg_$0) as count FROM dblink('host',pool_parallel('select count(*) from t1 ') as t1(arg_$0 bigint); 各ノードでcount(*) を計算した後に、システムDBで集計(sum)をすることによ り、目的が達成できます。 上記のようなクエリ書き換えが行われる条件は以下の場合です。
例) select bid,max(aid) from accounts wehre bid%2 = 0 group by bid; →クエリ書き換え SELECT bid,max(args_$0) FROM dblink('host','SELECT pool_parallel("select bid, max(aid) from accounts where bid%2 = 0 group by bid")) AS accounts(bid integer, args_$0 numeric) GROUP BY bid; 例外的なクエリクエリがシステムDBの情報に存在しないテーブルを参照している場合やシステム カタログ参照時には、クエリ書き換えを行わずに、クエリをノードへ送信し、バ ックエンドでの実行結果をそのままフロントエンドに返却します。 リリースノート1.3 (sohiboshi) 2007/10/23
1.2.1 (tomoboshi) 2007/09/28
1.2 (tomoboshi) 2007/08/01
1.1.1 (amiboshi) 2007/06/15
1.1 (amiboshi) 2007/05/25
1.0.2 (suboshi) 2007/02/13
|