Last modified: Sat Apr 5 19:42:52 JST 2014

ストリーミングレプリケーションとpgpool-IIの組み合わせ、簡単設定法(複数サーバ編)

概要

このチュートリアルでは、ストリーミングレプリケーションとpgpool-IIの組み合わせの簡単設定法を説明します。 Linuxが動くマシンが3台必要です(もちろん仮想環境でもOK)。 それぞれのマシンにPostgreSQLのインスタンス、pgpool-II(とpgpoolAdmin)をインストールします(1台のマシンで済ませてしまう方法はここにあります)。

この設定は非常に単純なものですが、それでもPostgreSQL 9.3自体に不足している以下のような機能を実現できます。

この構成では、pgpool-IIの動いているマシンがダウンするとデータベースとしての利用が停止してしまいます(いわゆる単一障害点(Single Point of Failure)。この問題を回避するには、pgpool-II の watchdog 機能を使ってpgpool-IIが動いているマシンを二重化します。 pgpool-HAはオープンソースで提供されており、pgpool-IIの開発サイトから入手できます。

システムの全体図を示します。

ここでは、サーバ1(ホスト名を"osspc16"とします)にpgpool-IIとpgpoolAdminが、サーバ2(ホスト名を"osspc17"とします)にプライマリのPostgreSQLが、サーバ3(ホスト名"osspc18"とします)がスタンバイサーバに割り当てられます。 なお、このプライマリとスタンバイの役割は相互に交換可能で、ここで言っているのは初期状態過ぎません。

PostgreSQL 9.3のインストール

PostgreSQL 9.3を3台のマシンすべてにインストールします。 osspc16ではPostgreSQLを動かしませんが、pgpoolをビルドするのに必要です。

PostgreSQLをインストールするもっとも簡単な方法は、PostgreSQLのオフィシャルサイトからLinux用のパッケージをダウンロードすることです。

他に、PostgreSQLをソースコードから導入する方法もあります。 これは驚くほど簡単です。tar ballを展開し、configure;make;make installとするだけです。 詳細はPostgreSQLのマニュアルをご覧ください。

次に、データベースクラスタをosspc17とosspc18上に作ります。 データベースクラスタは/home/postgres/dataにあり、postgresユーザに所有されているものとします。 以下の操作をosspc17とosspc18の両方で行ってください。

$ initdb -D /home/postgres/data

次に以下を /home/postgres/data/postgresql.conf に追加します。 "logging_collector"以下は ストリーミングレプリケーションには直接関係ありませんが、こうすることによって管理が簡単になります。 実際のシステムでは、log_statement = 'all'は削除した方が良いかもしれません。

listen_address = '*'
hot_standby = on
wal_level = hot_standby
max_wal_senders = 1
logging_collector = on
log_filename = '%A.log'
log_line_prefix = '%p %t '
log_truncate_on_rotation = on
log_statement = 'all'

pg_hba.confを/home/postgres/dataに設定します。 もちろん、"/some/where/" の部分はスクリプトをダウンロードした場所に置き換えてください。 注意: ここでの設定は、すべてのIPアドレスからのアクセスを許す非常に緩いものになっています。 実際のシステムでは、PostgreSQLのマニュアルにしたがって適切なアクセス権限を行ってください。

$ cp /some/where/pg_hba.conf" /home/postgres/data"

設定が終わったら、osspc17とosspc18のPostgreSQLを起動します。 この時点では、osspc17とosspc18はプライマリとして起動されます。 (まだストリーミングレプリケーションにはなっていません)

$ pg_ctl -D /home/postgres/data start

次に、osspc17とosspc18のpostgresユーザがお互いにパスワードなしでsshでログインできるようにします。 postgresユーザでssh-keygenを実行し、できた/home/postgres/.ssh/id_rsa.pubをお互いの/home/postgres/.ssh/authorized_keysに追加します。 追加したら、lsコマンドをssh経由で実行するなどして確認しておきましょう。

$ ssh osspc17 ls

pgpool-IIのインストール

osspc16にpgpool-IIをインストールします。 本稿で説明する設定では、pgpool-II 3.3.3以降が必要です。

以下を適当なユーザで実行します。 "postgres"ユーザが選ばれることが多いでしょう。

$ tar xfz /some/where/pgpool-II-3.3.3.tar.gz
$ cd pgpool-II-3.3.3
$ ./configure
$ make
$ sudo make install

次に、pgpoolが使用するユーザ定義関数をPostgreSQLにインストールします。 postgresユーザでosspc17とosspc18の両方で実施します。 文中使用している"install-functions.sh"は ここからダウンロードできます。もちろん、"/some/where/" の部分は実際にスクリプトをダウンロードした場所に読み替えてください。

$ tar xfz /some/where/pgpool-II-3.3.3.tar.gz
$ cd pgpool-II-3.3.3
$ ./configure
$ cd /tmp
$ cp /some/where/install-functions.sh .
$ sh install-functions.sh

次に pgpool-II の設定ファイルをosspc16にインストールします。 主要なファイルはpgpool.confです。 他にpcp.confがあります。 rootで以下を実行します。

# cp /some/where/pgpool.conf /usr/local/etc
# chown apache /usr/local/etc/pgpool.conf
# cp /some/where/pcp.conf /usr/local/etc
# chown apache /usr/local/etc/pcp.conf

ここでchownを実行している理由は、pgpoolAdminがこれらの設定ファイルを更新する必要があるからです。 pgpoolAdminはPHPスクリプトで、Apacheから実行されます。 もし pgpoolAdmin を使用しない場合(つまり、pcpコマンドラインツールだけを利用する)は、chownは必要ありません。

pcp.confの"postgres" アカウントの初期パスワードは "pgpoolAdmin"です。 インストール後、パスワードを速やかに変更することを強くおすすめします。 新しいパスワード文字列は pg_md5 コマンドを使って得ることができます。 詳細は pgpool-II doc をご覧ください。

オンラインリカバリを実行するために、basebackup.shpgpool_remote_start をosspc17とosspc18にインストールします。 pgpool_remote_start 中で、 pg_ctl コマンドへのパス名が指定されています。 実際のPostgreSQLのインストール状況に応じて、これを変更する必要があるかもしれません。

$ cp /some/where/baseback.sh /home/postgres/data
$ chmod 755 basebackup.sh
$ cp /some/where/pgpool_remote_start /home/postgres/data
$ chmod 755 pgpool_remote_start

osspc16に、自動フェイルオーバ処理で使うスクリプトfailover.shをインストールします。

$ sudo cp /some/where/failover.sh /usr/local/etc
$ sudo chmod 755 failover.sh

osspc16で必要なディレクトリを作ります。 以下をrootで実行してください。 ここでchownを実行している理由は、pgpoolAdminがこれらの設定ファイルを更新する必要があるからです。 pgpoolAdminはPHPスクリプトで、Apacheから実行されます。 もし pgpoolAdmin を使用しない場合(つまり、pcpコマンドラインツールだけを利用する)は、chownは必要ありません。

# mkdir /var/run/pgpool
# chown apache /var/run/pgpool
# mkdir /var/log/pgpool
# chown apache /var/log/pgpool

osspc17, osspc18で必要なディレクトリを作ります。 以下をrootで実行してください。

# mkdir -p /var/log/pgpool/trigger
# chown postgres /var/log/pgpool/trigger

pgpoolAdminを使う場合は、osspc16のapacheユーザがosspc17, osspc18のpostgresユーザにパスワードなしでsshでログインできるようにします。 ほとんどのシステムでは、apacheユーザのアカウントはログインできない設定になっているはずです。

apache:x:48:48:Apache:/var/www:/sbin/nologin

この/sbin/nologinを一時的に/bin/bashに変えるなどして、ログインできるようにします。 その上で/var/www/.sshディレクトリを作ります。そして、ssh-keygenを実行してssh環境を作ります。

# mkdir /var/www/.ssh
# chown apache /var/www/.ssh
# su - apache
$ ssh-keygen
:
:

/var/www/.ssh/にはid_rsa.pubというファイルができているはずなので、それをosspc17, osspc18の/home/postggres/.ssh/authorized_keysに追加します。 終わったら、osspc16のapacheユーザがosspc17, osspc18のpostgresユーザにsshでパスワードなしでログインできることを確認しておきます。

$ ssh postgres@osspc17 ls
$ ssh postgres@osspc18 ls

確認できたら、/etc/passwdのapacheのエントリを元に戻しておきます。 なお、実際のシステムに導入する場合は、pgpoolAdmin専用のアカウントを作り、そのアカウントで別途apacheを立ち上げることをおすすめします。

次にosspc17, osspc18でapache ユーザを作ります。

$ createuser apache
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

ここで、一旦osspc18のPostgreSQLを停止します。osspc18で以下を実行してください。

$ pg_ctl -D /home/postgres/data -m f stop

pgpoolAdminのインストール

pgpoolAdmin は、PHPで実装された pgpool-II の管理ツールです。 pgpoolAdminは、pgpool-IIを実行するサーバと同じサーバ上で実行しなければなりません。 これはすなわち、実質的にはpgpoolAdminはWindowsでは動作しないことを意味します。 pgpoolAdminはPHPが4.2以上であれば動作しますが、PostgreSQLにアクセスするための拡張がインストールされていることが必要です。 PHPをソースからインストールするときは --with-pgsql を付けてビルドしてください。 PHPをrpmからインストールする場合、一部のディストリビューション(たとえばVine Linux)ではPostgreSQL拡張が最初からバンドルされていますが、多くのディストリビューションでは、追加で入れる必要があります。

pgpoolAdmin にはインストーラが付属しているので、インストールは容易です。 本稿で説明する設定では、pgpoolAdmin 3.3.1以降が必要です(もしくはCVS HEAD)。 Apacheのドキュメントディレクトリ(たとえば/var/www/html/)で展開後、 インストール説明読んでください。 インストーラでpgpoolAdminをインストールする際のポイントを説明します。 まず以下を実行します。

# cd /var/www/html/pgpoolAdmin-3.3.1
# chmod 777 templates_c
# chown apache conf/pgmgt.conf.php
# chmod 644 conf/pgmgt.conf.php

準備ができたら、pgpoolAdminインストーラを適当なブラウザで開きます。 この例では、URLは http://osspc16/pgpoolAdmin-3.3.1/install/index.php になります。 このページが表示されるはずです。 ここでLanguageメニューから日本語を選べば、実際には以後の画面は日本語表示になります。 "Next" を選ぶと この画面になります。 すべての項目が緑でチェックされていることを確認してください。 それならすべてOKということです。 "Next"を選択し、主設定画面に移動します。 デフォルト値から変更を推奨するのは以下の項目です。

説明通りに設定すると、このような画面になるはずです。 これでpgpoolAdminのインストールは終わりです。お疲れ様!

pgpool-IIの起動

pgpoolAdminにログインしてpgpool-II を 「pgpoolステータス」から起動します。 osspc17、ポート番号5432のPostgreSQL が プライマリサーバとして実行中となっているはずです。 osspc16、ポート番号5432、psqlからpgpool-IIに接続できます。 テーブルを作ってみましょう。

$ createdb -h osspc16 test
$ psql -h osspc16 test
test=# create table t1(i int);
CREATE TABLE
test=#

pgpoolのログには次のように表示されているはずです。

$ tail /var/log/pgpool/pgpool.log.Friday
2014-04-04 15:17:20 LOG:   pid 5716: DB node id: 0 backend pid: 6036 statement: create table t1(i int);

同じクエリのログがosspc17, osspc18のPostgreSQLのログにも表示されます。

$ tail /home/postgres/data/pg_log/Fri.log
6036 2014-04-04 15:17:22 JST LOG:  statement: create table t1(i int);

スタンバイサーバの起動

この時点では、スタンバイサーバは動いていません。 スタンバイサーバを起動するには、「リカバリ」(Recovery) ボタンを選択します。 "basebackup.sh" が起動され、しばらくするとスタンバイサーバが 自動的に起動されます

スタンバイサーバが動き出したので、レプリケーションが始まっています。 データをt1テーブルに登録してみましょう。

-- insert into t1 via pgpool-II.
-- it will be executed on primary server
psql -h osspc16 test
test=# insert into t1 values(1);
test=# \q
psql -h osspc18 test
-- now connected to standby server
test=# select * from t1;
 i
---
 1
(1 row)

スタンバイサーバがダウンしたら?

スタンバイサーバがダウンすると、pgpool-IIはそれを切り離します。 ユーザがpgpool-II経由で普通にSQLを発行できます。 ストリーミングレプリケーションはもちろん止まっています。 スタンバイサーバを復旧するには、「リカバリ」(Recovery) ボタンを選択します。

プライマリサーバがダウンしたら?

慌てることはありません。 スタンバイサーバはこのために用意されているのです。 osspc17がプライマリだったとして、試しにダウンさせてみます。

$ pg_ctl -D /home/postgres/data -m f stop

ごらんのように、プライマリのPostgreSQLがダウンすると、スタンバイであるosspc18のPostgreSQL が旧プライマリサーバに取って代わります。 pgpool-IIは、プライマリサーバがダウンしているのを検知すると、フェイルオーバスクリプト(failover.sh)を実行します。 このスクリプトは/var/log/pgpool/trigger/trigger1をトリガファイルとしてosspc18のスタンバイサーバ上に作成します。 スタンバイサーバはこのファイルを発見すると、プライマリに昇格します。 osspc16のPostgreSQLの「リカバリ」(Recovery)ボタンを選択すると、旧プライマリは スタンバイサーバとして復旧します

まとめ

PostgreSQL 9.3 は単純で使いやすい組み込みレプリケーションをサポートしています。 pgpool-IIをその上に組み込むことにより、高可用性システム(HA)を構築することができます。

質問やコメントがあれば、pgpoolメーリングリストまでお寄せください。

石井達夫
ishii at sraoss.co.jp