7.1. 基本設定の例

7.1.1. さあ始めましょう

ここでは、レプリケーションを行うための準備として、Pgpool-II のインストールや設定、データベースノードの準備について説明します。

7.1.1.1. Pgpool-IIのインストール

Pgpool-IIのインストールはとても簡単です。 ソースのtar ballを展開したディレクトリで以下のようにコマンドを実行します。

$ ./configure
$ make
$ make install
          

configureスクリプトはシステム情報を収集しコンパイル処理に利用します。 configureスクリプトにコマンドライン引数を指定することにより、インストール先ディレクトリなど、デフォルトの動作を変更することができます。 デフォルトではPgpool-II/usr/localディレクトリ以下にインストールされます。

makeコマンドはソースコードはコンパイルし、make installコマンドで実行可能ファイルがインストールされます。 インストール先ディレクトリに書き込み権限を持っている必要があります。 ここでは、Pgpool-II/usr/localにインストールすることにします。

注意: Pgpool-IIPostgreSQL 7.4 以降のlibpqライブラリ(3.0 プロトコル)を必要とします。

configureスクリプトが以下のエラーメッセージを表示した場合、libpqライブラリがインストールされていないか、バージョンが3.0でない可能性があります。

configure: error: libpq is not installed or libpq is old
          

プロトコルのバージョンが3.0のlibpqライブラリがインストールされているにも係わらず上記のエラーメッセージが表示される場合、configureスクリプトにlibpqライブラリが認識されていない可能性があります。 configureスクリプトは標準では/usr/local/pgsqlディレクトリ以下からlibpqライブラリを検索します。 PostgreSQLのインストール先が/usr/local/pgsqlディレクトリ以下でなければ、configureスクリプトを実行する際にコマンドライン引数として--with-pgsql--with-pgsql-includedir--with-pgsql-libdirオプションを指定してください。

7.1.1.2. 設定ファイルの作成

Pgpool-IIの設定パラメータはpgpool.confファイルに保存されてします。 ファイルは、1 行ごとにパラメータ名 = 値という書式です。 Pgpool-II をインストールすると、pgpool.conf.sampleファイルが作成されます。 それをpgpool.confというファイル名にコピーしてから編集するといいでしょう。

$ cp /usr/local/etc/pgpool.conf.sample /usr/local/etc/pgpool.conf
          

Pgpool-II はローカルホストからのポート番号9999への接続のみを受け付けます。 Pgpool-II と異なるホストからの接続を受け付けたい場合は、listen_addresses'*'に設定します。

listen_addresses = 'localhost'
port = 9999
          

ここではデフォルトのパラメータを使うことにします。

7.1.1.3. PCPコマンドの設定

Pgpool-IIには、データベースノードの情報取得やPgpool-II停止などをネットワーク越しに行える管理目的のインターフェイスがあります。 PCPコマンドを使用するにはユーザ認証が必要になります。 この認証はPostgreSQLユーザの認証とは異なります。 ユーザ名とパスワードがpcp.confファイルに定義されている必要があります。 このファイルでは、1行ごとにユーザ名とパスワードがペアとしてリストされており、これららコロン(:)で区切られています。 パスワードはMD5ハッシュ形式で暗号化されています。

postgres:e8a48653851e28c69d0506508fb27fc5
          

Pgpool-II をインストールするとサンプルとしてpcp.conf.sampleが自動的に生成されます。 それをpcp.confというファイル名にコピーしてから編集するといいでしょう。

$ cp /usr/local/etc/pcp.conf.sample /usr/local/etc/pcp.conf
          

パスワードをMD5ハッシュ形式に変換する際には、Pgpool-IIとともにインストールされるpg_md5コマンドを使用します。 pg_md5コマンドは、コマンドライン引数として文字列を指定すると、それをMD5ハッシュ化したものを表示します。 例えば、以下のようにコマンドライン引数として"postgres"を指定して実行すると、それをMD5ハッシュ化しテキストが標準出力に表示されます。

$ /usr/bin/pg_md5 postgres
e8a48653851e28c69d0506508fb27fc5
          

PCPコマンドはネットワークを通して実行されるので、ポート番号をpgpool.confファイルのpcp_portパラメータに設定します。 ここでは、pcp_portのデフォルトである9898を使用することにします。

pcp_port = 9898
          

7.1.1.4. データベースノードの準備

次に、Pgpool-IIのためのPostgreSQLサーバを設定する必要があります。 これらのサーバは、Pgpool-II と同じホストで起動しても、異なるホストであっても構いません。 同じホストにサーバを配置するのならば、各サーバにそれぞれ異なるポート番号を割り合てなければなりません。 異なるマシンで起動する場合は Pgpool-IIからのネットワーク接続を受け入れられるよう適切に設定されている必要があります。 が起動するホストからデータベースサーバに接続できるように設定する必要があります。 Pgpool-II ではデータベースサーバごとにレプリケーションを行うので、チュートリアルのためのデータベースクラスタを作成したほうがいいでしょう。

backend_hostname0 = 'localhost'
backend_port0 = 5432
backend_weight0 = 1
backend_hostname1 = 'localhost'
backend_port1 = 5433
backend_weight1 = 1
backend_hostname2 = 'localhost'
backend_port2 = 5434
backend_weight2 = 1
          

backend_hostnamebackend_portbackend_weightには、ノードのホスト名、ポート番号、負荷分散の割合を設定します。 各パラメータ名の後ろには、ノードIDが0から始まる整数(すなわち、0, 1, 2, ...)で指定されていなければなりません。

注意: すべてのノードでbackend_weightパラメータが1に設定してるのは、SELECTクエリが3台のサーバで等しく分散されることを意味しています。

7.1.1.5. Pgpool-IIの起動と停止

Pgpool-II を起動するにはターミナルで以下のコマンドを実行します。

$ pgpool
        

しかしこれでは、Pgpool-IIが制御端末を切り離すため、ログが出力されません。 Pgpool-IIにログメッセージを表示させたい場合、pgpoolコマンドに-nオプションを指定すると、Pgpool-IIは非デーモンプロセスとして起動し、制御端末は切り離されません。

$ pgpool -n &
        

コマンドを実行した端末にログメッセージが表示されるので、以下のようなオプションを使うことをお勧めします。

$ pgpool -n -d > /tmp/pgpool.log 2>&1 &
        

-d オプションはデバッグメッセージの出力を有効にします。 上記の例はファイルにリダイレクトさせているため、ログメッセージが/tmp/pgpol.log追加され続けます。 ログをローテートさせたい場合は、ローテート機能を持った外部コマンドにログを渡してください。 たとえば、Apache2のrotatelogsが使用できます。

$ pgpool -n 2>&1 | /usr/local/apache2/bin/rotatelogs \
  -l -f /var/log/pgpool/pgpool.log.%A 86400 &
        

これにより毎日夜中の0時にログがローテートされ、pgpool.log.Thursdayのような名前のログファイルが毎日作成されます。 ただし、すでに同じ名前のファイルがある場合にはrotatelogsはログをそのファイルに追加してしまいます。 cronを使うことで、古いログファイルをローテーションの前に削除することができます。

55 23 * * * /usr/bin/find /var/log/pgpool -type f -mtime +5 -exec /bin/rm -f '{}' \;
        

注意:Linuxディストリビューションによっては、rotatelogsはusr/sbin/rotatelogs2として存在しているかもしれません。 -fオプションはrotatelogsが起動された直後に直ちにログファイルを作るオプションで、apache2 2.2.9以降でのみ有効です。 cronologを使うこともできます。

$ pgpool -n 2>&1 | /usr/sbin/cronolog \
  --hardlink=/var/log/pgsql/pgpool.log \
  '/var/log/pgsql/%Y-%m-%d-pgpool.log' &
        

Pgpool-II を停止するには以下のコマンドを実行します。

$ pgpool stop
        

Pgpool-II を停止する際にクライアントが接続している場合、Pgpool-IIはその接続が切断されるまで待ってから停止します。 Pgpool-IIを強制的にシャットダウンしたい場合は、以下のコマンドを実行します。

$ pgpool -m fast stop
        

7.1.2. 初めてのレプリケーション

レプリケーション(項5.3.2を参照)では複数のデータベースノードに同じデータを複製して格納します。 ここでは、項7.1.1で準備した 3 台のデータベースノードを使用し、一歩一歩データベースクラスタシステムを作っていきまししょう。 複製させるサンプルのデータpgbenchベンチマークプログラムで生成することにします。

7.1.2.1. レプリケーションの設定

データベースノードのレプリケーションを有効にするには、pgpool.confファイルのreplication_modeをonに設定します。

replication_mode = true
        

replication_modeをonに設定することにより、Pgpool-IIは受信したクエリを全てのデータベースノードに送信します。 対して実行され、同じデータが複製されて格納されるようになります。 さらに、load_balance_modeをonに設定することにより、Pgpool-IIはSELECTクエリをデータベースノード間に振り分けます。

load_balance_mode = true
        

ここでは、replication_modeload_balance_modeの両方を有効にします。

7.1.2.2. レプリケーションの確認

pgpool.confの変更をPgpool-IIに反映させるにはPgpool-IIを再起動する必要があります。 「Pgpool-II の起動と停止」項7.1.1.5を参照してください。 pgpool.confの設定と再起動がすんだら、実際にレプリケーションを試してうまく行くことを確認しましょう。 まず、複製するデータベースを作成する必要があります。 これを"bench_replication"と名づけましょう。 このデータベースが全てのノードで作成される必要があります。 createdbコマンドをPgpool-II経由で実行すると、すべてのノードでデータベースが作成されます。

$ createdb -p 9999 bench_replication
          

そしてpgbench-iオプションを指定して実行します。 -iオプションにより、データベースは事前に定義されたテーブルとデータで初期化されます。

$ pgbench -i -p 9999 bench_replication
          

pgbench -iによいって作成されるテーブルとデータを以下の表にまとめます。 すべてのノードにおいてこれらのテーブルおよびデータが作成されていれば、正常にレプリケーションが動作していることになります。

表 7-1. data summary

テーブル名行数
branches1
tellers10
accounts100000
history0

これをチェックするため、簡単なシェルスクリプトを実行してみましょう。 以下のスクリプトはすべてのノード (ポート番号 5432、5433、5434) のデータベースにおけるbranches、tellers、accounts、historyの行数が表示されます。

$ for port in 5432 5433 5434; do
>     echo $port
>     for table_name in branches tellers accounts history; do
>         echo $table_name
>         psql -c "SELECT count(*) FROM $table_name" -p $port bench_replication
>     done
> done