5.3. 動作モード

5.3.1. マスタースレーブモード

このモードはPgpool-IIと(Slony-Iやストリームレプリケーションのような)他のマスター/スレーブ型のレプリケーションソフトウェアと組み合わせるのに使用されます。 実際にデータレプリケーションを行うのはこれらのソフトウェアに任されます。

注意: スレーブノードの数は1つに限定されず、Pgpool-IIは127個までのスレーブノードを持つことができます。 マスタースレーブモードは、スレーブノードが1つも存在しない場合マスターノードのみを動作させることができます。

参照負荷をスタンバイバックエンドノードに振り分ける負荷分散(項5.7を参照)もマスタースレーブモードと共に使用可能です。

マスタースレーブモードでは以下のオプションを設定する必要があります。

master_slave_mode (boolean)

マスタースレーブモードを有効にします。 デフォルトはoffです。

注意: master_slave_modereplication_modeは相互に排他的で、一度に一方しか有効にすることができません。

このパラメータはサーバ起動時にのみ設定可能です。

master_slave_sub_mode (enum)

PostgreSQLノード間のデータレプリケーションに用いる外部のレプリケーションシステムを指定します。 以下の表にこのパラメータで有効な値のリストを示します。

表 5-1. master_slave_sub_modeオプション

説明
'slony' Slony-Iに適合
'stream'PostgreSQLの組み込みレプリケーションシステム(ストリーミングレプリケーション)に適合
'logical'PostgreSQLの組み込みレプリケーションシステム(ロジカルレプリケーション)に適合

デフォルトは'slony'です。

このパラメータはサーバ起動時にのみ設定可能です。

5.3.2. レプリケーションモード

このモードではPostgreSQL間のデータレプリケーションをPgpool-IIに行わせます。

参照負荷をスタンバイバックエンドノードに振り分ける負荷分散(項5.7を参照)もレプリケーションモードと共に使用可能です。

以下のオプションがレプリケーションモードにおけるPgpool-IIの動作に影響します。

replication_mode (boolean)

レプリケーションモードを有効にします。 デフォルトはoffです。

注意: replication_modemaster_slave_modeは相互に排他的で、一度に一方しか有効にすることができません。

このパラメータはサーバ起動時にのみ設定可能です。

replication_stop_on_mismatch (boolean)

これがonで、全てのPostgreSQLバックエンドノードに送られたクエリに対して、全てのノードが同じパケット種類で応答しなかった場合、多数派とは異なる応答したバックエンドノードはPgpool-IIにより切り離されます。 replication_stop_on_mismatchがoffの場合に同様の状況が発生したときには、Pgpool-IIは現在のユーザセッションを強制終了するだけにとどめ、バックエンドの切り離しは行いません。

注意: Pgpool-IIはバックエンドから返されたデータは調べずに、結果パケットの種類の比較のみにより決断します。

replication_stop_on_mismatchを有効にする典型的なユースケースは、バックエンドノード間のデータ不整合の防止です。 例えば、UPDATE文が他のノードでは成功しているのにあるバックエンドノードでは失敗した場合、そのバックエンドノードを切り離したいかもしれません。

デフォルトはoffです。

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

failover_if_affected_tuples_mismatch (boolean)

これがonで、全てのノードの応答でINSERT/UPDATE/DELETEクエリの影響を受けたタプルの数が同じでなかった場合、多数派とは異なる応答したバックエンドノードはPgpool-IIによる切り離されます。 failover_if_affected_tuples_mismatchがoffの場合に同様の状況が発生したときには、Pgpool-IIは現在のユーザセッションを強制終了するだけにとどめ、バックエンドの切り離しは行いません。

注意: もし同票で、2つ以上のグループで同じノード数だった場合は、マスターノード(最も若いDBノード番号のバックエンドノード)を含むグループが優先されます。

デフォルトはoffです。

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

replicate_select (boolean)

onを設定すると、Pgpool-IIはSELECTクエリのレプリケーションモードを有効にします。 すなわち、SELECTクエリが全てのバックエンドノードに送信されます。

表 5-2. replicate_selectとload_balance_modeがSELECTのルーティングに与える影響

replicate_selectがtrueYN
load_balance_modeがtrueANYYN
SELECTがトランザクションブロックの内部にあるANY Y NANY
トランザクション分離レベルがSERIALIZABLEで、トランザクションが更新クエリを発行済 ANYYNANYANY
結果(R:レプリケーション、M:マスターのみに送信、L:負荷分散) RMLLM

デフォルトはoffです。

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

insert_lock (boolean)

onに設定すると、Pgpool-IIはINSERT文が発行される前にPostgreSQL上のテーブルを自動的にロックします。

SERIAL型を使っているテーブルをレプリケーションすると、SERIAL型の列の値がDBノードの間で一致しなくなることがあります。 この問題の回避策は、INSERT実行前に該当テーブルを明示的にロックすることです。

テーブルの自動ロックのため、Pgpool-IIは以下の変換を行います。

INSERT INTO ...
							

これを次のように変換します。

BEGIN;
LOCK TABLE ...
INSERT INTO ...
COMMIT;
							

注意

この方法はトランザクションの並列実行性を大きく劣化させます。

Pgpool-II V2.2以降では、テーブルがSERIAL列を持つかどうか自動判別するため、SERIAL列がなければ決してテーブルをロックしません。

Pgpool-II V3.0.4までのPgpool-II V3.0では、テーブルロックではなくシーケンステーブルに対して行ロックをかけます。 これはVACUUM(autovacuumを含む)とのロック競合を最小化することを意図しています。 しかし、これは他の問題を引き起こします。 トランザクション周回が起きた後、シーケンステーブルに対する行ロックはPostgreSQLの内部エラー (詳細には、トランザクション状態を保持するpg_clogへのアクセスエラー)を起こします。 これを防ぐため、PostgreSQLのコア開発者はシーケンステーブルに対する行ロックを許可しないことを決定しました。 これはもちろんPgpool-IIを動作不能にします(修正されたPostgreSQLはバージョン 9.0.5, 8.4.9, 8.3.16そして8.2.22としてリリースされました)。

Pgpool-II V3.0.5以降では、新しいPostgreSQLがシーケンステーブルに対するロックを許可しなくなったため、pgpool_catalog.insert_lockテーブルに対して行ロックをかけます。 したがって、Pgpool-II経由でアクセスするすべてのデータベースにinsert_lockテーブルをあらかじめ作成しておく必要があります。 詳細は項3.7をご覧ください。 もし、insert_lockテーブルが存在しない場合は、挿入対象のテーブルに対してロックを行います。 これは、Pgpool-II V2.2V2.3シリーズと同じ動作です。

過去のバージョンと互換性のあるinsert_lockを使用したい場合は、configureスクリプトでロック方法を指定できます。 詳細は項3.4をご覧下さい。

(文ごとの)細かい制御:

  • insert_lockをtrueにして、テーブルロックを獲得してほしくないINSERT文には、先頭に/*NO INSERT LOCK*/コメントを追加します。

  • insert_lockをfalseにして、テーブルロックを獲得してほしいINSERT文には、先頭に/*INSERT LOCK*/コメントを追加します。

注意: insert_lockを有効にしてregression testを実行すると、PostgreSQL 8.0では transactions, privileges, rules, alter_tableがfailします。

その理由は、ruleテストでPgpool-IIがビューにLOCKを実行しようとするため、そして以下のエラーメッセージが出てしまうためです。

! ERROR: current transaction is aborted, commands ignored until
end of transaction block
							

たとえば、transactionsテストでは、存在しないテーブルに対してINSERTを試みており、Pgpool-IIPostgerSQLにそのテーブルのロックを獲得させることになります。 これはもちろんエラーとなります。 トランザクションがアボート状態になり、続くINSERTでは上記エラーが出てしまいます。

デフォルトはoffです。

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

lobj_lock_table (string)

ラージオブジェクトのレプリケーションを行いたいときにロック管理に使うためのテーブル名を指定します。 このテーブルが指定されている場合、Pgpool-IIは、lobj_lock_tableで指定されているテーブルをロックした後、pg_largeobjectシステムカタログを参照してラージオブジェクトIDを生成し、lo_create()を呼び出してラージオブジェクトの作成を行います。 この方法により、レプリケーションモードにおいてPgpool-IIが全てのDBノードで同じラージオブジェクトIDを得られることが保証されます。

注意: PostgreSQL 8.0以前はlo_createを持たないため、PostgreSQL 8.0以前のバージョンではこの処理は行われません。

libpqの関数lo_creat()の呼び出しがこの機能の契機となります。 Java API(JDBCドライバ)、PHP API(pg_lo_create、またはPDOといったPHPライブラリの同様のAPI)、様々なプログラミング言語の同様のAPIを経由したラージオブジェクトの生成においても同じプロトコルが使われることがわかっているので、この機能は動作するはずです。

この機能はラージオブジェクトに対する以下の操作では動作しません。

  • lo_createlo_import_with_oidを使う全てのAPI。

  • バックエンドのlo_import関数をSELECTで呼び出す場合

  • バックエンドのlo_create関数をSELECTで呼び出す場合

注意: 全てのPostgreSQLユーザはlobj_lock_tableへ書き込み可能である必要が有ります。 また、これはどのスキーマに作成されてもかまいません。

ラージオブジェクトロックテーブルを作る例を示します。

CREATE TABLE public.my_lock_table ();
GRANT ALL ON public.my_lock_table TO PUBLIC;
						

デフォルトは''(空文字列)で、この機能は無効です。