Last modified: Sat Apr 5 19:42:52 JST 2014
このチュートリアルでは、ストリーミングレプリケーションと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を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
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.sh と pgpool_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 は、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のインストールは終わりです。お疲れ様!
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