2.クイックスタート
2007.2.28 株式会社四次元データ 宮澤了祐・内田康介
- 2.1. pgpool-II
- 2.2. PGCluster
- 2.3. PostgresForest
- 2.4. ウォームスタンバイ
2.1.pgpool-II
インストール
pgpool-IIのインストールにあたって、三台のPostgreSQLサーバが動作する環境が出来ていることを前提とします。 それぞれの待ちうけポートは「6000」「6001」「6002」番だとします。
まず、pgpool-II公式サイトよりpgpool-IIをダウンロードします。 執筆時の最新バージョンは1.0.1です。
適当な箇所に展開し、ビルドを行います。
tar -zxvf pgpool-II-1.0.1.tar.gz cd pgpool-II-1.0.1 ./configure --prefix=/usr/local/pgpool2 --with-pgsql=/usr/local/pgsql/8.1/ make make install
インストール先を「/usr/local/pgpool2」に設定しています。 また、pgpool-IIのインストールには、PostgreSQL7.4以降のlibpqライブラリが必要ですので、PostgreSQLのインストール先を指定します。 なお、インストール先がデフォルトの「/usr/local/pgsql」であった場合は指定する必要ありません。
次に、pgpool-IIが使用するシステムDBをポート「6000」番で動いているPostgreSQLに構築します。
システムDBには、dblinkというcontribモジュールが必要です。このモジュールは、PostgreSQLのソースファイル内にありますので、 コンパイルして、インストールを行います。
cd contrib/dblink/ make make install psql -p 6000 -f dblink.sql
次に、システムDBにpgpool-IIが使用するデータベースを構築します。テーブル構成などは、サンプルコンフィグレーションファイルがありますので、 それを利用します。
createdb -p 6000 pgpool psql -p 6000 -f /usr/local/pgpool2/share/system_db.sql pgpool
これでシステムDBの構築が終了です。
設定
次に、pgpool-II本体の設定ファイルを作成し、必要な箇所を書き換えます。
cd /usr/local/pgpool2/etc cp pgpool.conf.sample pgpool.conf vi pgpool.conf
まずはpgpool-IIの動作するポート番号です。pgpool-IIでは動作用ポートと管理用ポートを使用しており、標準では「9999」「9898」に設定されています。今回は特に変更しません。
# Port number for pgpool port = 9999 # Port number for pgpool communication manager pcp_port = 9898
レプリケーションモードを有効に設定します。
# replication mode replication_mode = true
システムDBの情報を設定します。
system_db_hostname = 'localhost' system_db_port = 6000 system_db_dbname = 'pgpool' system_db_schema = 'pgpool_catalog' system_db_user = 'pgpool' system_db_password = ''
接続するノードを設定します。 ここでは「6001」番ポートと「6002」番ポートで動作するように設定します。
# backend_hostname, backend_port, backend_weight backend_hostname0 = '' backend_port0 = 6001 backend_weight0 = 1 backend_hostname1 = '' backend_port1 = 6002 backend_weight1 = 1
接続するノードごとに、ホスト名・ポート番号・負荷分散の比率を設定します。今回はホスト名が「''」となっていますが、これは、ローカルにUNIXドメインソケットで接続しているためです。
管理ポートを使用するための、ユーザ設定ファイルを作成します。
cd /usr/local/pgpool2/etc cp pcp.conf.sample pcp.conf
このファイルに、管理ポートを使用するユーザ名とMD5でハッシュ化したパスワードを記述します。今回は、ユーザ名・パスワードとも「postgres」というユーザを作成します。 なお、ハッシュ化には、pg_md5というコマンドを使用します。
/usr/local/pgpool2/bin/pg_md5 postgres e8a48653851e28c69d0506508fb27fc5
この実行結果を、先ほど作成した「pcp.conf」に記述します。
vi pcp.conf postgres:e8a48653851e28c69d0506508fb27fc5
起動・終了
起動を行うにはシェルから次のコマンドを実行します。今回は、ログを「/tmp/pgpool.log」に書き出すようにしています。 終了する場合は「stop」オプションをつけて実行します。
起動 /usr/local/pgpool2/pgpool -d -n >/tmp/pgpool.log 2>&1f 終了 /usr/local/pgpool2/pgpool stop
「psql」などを用いて先ほど設定したポートに接続し、レプリケートが出来ているかを確認してください。
psql -p 9999
2.2.PGCluster
インストール
PgFoundry:PGClusterよりPGClusterをダウンロードし、ビルドを行います。 PostgreSQLを同梱しているものと、パッチをあてるものの二種類があります。ここではPGCluster1.5rc7(PostgreSQL同梱版)を対象に行います。 なお、PGClusterでは復旧作業にrsyncが必要となります。
tar -zxvf pgcluster-1.5.0rc7.tar.gz cd pgcluster-1.5.0rc7 ./configure --prefix=/usr/local/pgcluster make make install
/usr/local/pgcluster以下にインストールするように設定します。
設定
PGClusterの設定ファイルには次のものがあります。
- クラスタDBの設定ファイル
postgresql.conf、pg_hba.conf、cluster.conf - レプリケーションサーバの設定ファイル
pgreplication.conf - ロードバランサの設定ファイル
pglb.conf
ここではロードバランサを使用しない構成(クラスタDB2台、レプリケーションサーバ1台)で作成したいと思います。
サーバ名 | ポート番号 | 説明 |
レプリケーションサーバ | 8001 リカバリーポート:8101 |
レプリケーションを行うサーバです。 |
クラスタDB1 | 6001 リカバリーポート:7001 |
一台目のクラスタDBです。 |
クラスタDB2 | 6002 リカバリーポート:7002 |
二台目のクラスタDBです。 |
まずはクラスタDBを作成します。「/usr/local/pgcluster/」以下に「db1」「db2」の二台のクラスタDBを作成します。
cd /usr/local/pgcluster/bin ./initdb -D /usr/local/pgcluster/db1 ./initdb -D /usr/local/pgcluster/db2
各々のpostgresql.conf、及びpg_hba.confを環境に合わせて設定します。
vi postgresql.conf (db1) listen_addresses = '*' port = 6001 (db2) listen_addresses = '*' port = 6002 vi pg_hba.conf (db1) host all all 192.168.0.0/24 trust (db2) host all all 192.168.0.0/24 trust
続いて、cluster.confを編集します。
vi cluster.conf <Replicate_Server_Info> <Host_Name> example.techscore.com </Host_Name> <Port> 8001 </Port> <Recovery_Port> 8101 </Recovery_Port> </Replicate_Server_Info> <Recovery_Port> 7001 </Recovery_Port> <Rsync_Path> /usr/bin/rsync </Rsync_Path> <Rsync_Option> ssh -1 </Rsync_Option> <When_Stand_Alone> read_only </When_Stand_Alone>
PGClusterではrsyncという同期を取るためのプログラムを利用して障害後の復旧を行います。 そのため、rsyncのパスを指定する必要と、リカバリ要求を受け取るためのポート番号を指定する必要があります。 なお、上記では、rsync は /usr/bin/rsync にインストールされているものとしています。 このパスについてはご利用の環境に合わせて指定して下さい。
また、クラスタDB2のRecovery_Portは7002になるように設定してください。
次に、レプリケーションサーバの設定を行います。設定ファイルは「/usr/local/pgcluster/share/postgresql」以下にあります。
cd /usr/local/pgcluster/share/postgresql cp pgreplicate.conf.sample pgreplicate.conf vi pgreplicate.conf
<Cluster_Server_Info> <Host_Name>exmaple.techscore.com</Host_Name> <Port>6001</Port> <Recovery_Port>7001</Recovery_Port> </Cluster_Server_Info> <Cluster_Server_Info> <Host_Name>example.techscore.com</Host_Name> <Port>6002</Port> <Recovery_Port>7002</Recovery_Port> </Cluster_Server_Info>
<Replication_Port> 8001 </Replication_Port> <Recovery_Port> 8101 </Recovery_Port> <Response_Mode> normal </Response_Mode> <Use_Replication_Log> yes </Use_Replication_Log> <RLOG_Port> 8301 </RLOG_Port>
起動・終了
レプリケーションサーバを起動します。「-D」オプションを使用し、設定ファイルを指定します。終了するには「stop」オプションを指定します。
cd /usr/local/pgcluster/bin ./pgreplicate -D /usr/local/pgcluster/share/postgresql ./pgreplicate -D /usr/local/pgcluster/share/postgresql stop
クラスタDBを起動します。クラスタDBはPostgreSQLのインスタンスを起動するのと同じ方法で起動・終了が出来ます。
pg_ctl -D /usr/local/pgcluster/db1 start pg_ctl -D /usr/local/pgcluster/db2 start
psqlなどでクラスタDBのどちらかに接続し、レプリケーションが行われていることを確認して下さい
psql -p 6001
2.3.PostgresForest
PL/Javaについて
PL/Javaとは、Java言語でPostgreSQL用のストアドプロシージャーを記述することの出来る言語です。
Windows用のPostgreSQLにはインストーラーに付属していますが、Linux用などでは別途インストールする必要があります。
ストアドプロシージャーについては以下を参照して下さい。
なお、PostgresForestでは、PL/Javaを使用しています。
インストール
PostgresForestのインストールにあたって、PostgreSQLがインストール済みであることを前提とします。 また、インストールの際Javaを使用するので、SunのJDK1.4以降が必要です。 なお、1台のサーバに複数のクラスタDBをインストールするとリカバリ時にエラーが発生しましたので、 『192.168.0.1』と『192.168.0.2』の2台のサーバを用意しました。
PostgresForest 株式会社NTTデータより、 PostgresForestをダウンロードし、展開します。ここでは最新バージョンのPostgresForest4.0を対象にします。
ダウンロードしたファイルを展開後、展開したディレクトリに移動し、設定ファイルを編集します。
unzip PostgresForest-4.0.zip cd PostgresForest-4.0 vi env.conf
# DESTDIR=/opt/forest/forest40 DESTDIR=/usr/local/forest40/ # JAVA environment JAVA_HOME=/usr/local/java/jdk1.5.0_10 # PostgreSQL environment PGHOME=/usr/local/pgsql PGUSER=forest PGPORT=6001 PGDATA=/usr/local/forest40/data
「DESTDIR」にPostgresForestのインストール先を、「PGHOME」にPostgreSQLのインストール先を指定します。
ビルドを実行します。
./build.sh
必要なファイルを配置するスクリプトをrootユーザで実行します。 全て問題なく完了すればメッセージが出力されます。
./install.sh =============================================== ====== All files installed successfully. ====== ===============================================
インストールが完了したら、データベースの初期化を行います。 初期化には、「forest_initdb」を利用します。
/usr/local/forest40/bin/forest_initdb
初期化が終了し、出来上がったディレクトリ内にある、「pg_hba.conf」「postmaster.conf」を各クラスタDB同士が通信できるように設定してください。
PostgreSQLのインスタンスの起動・終了は、「forest_ctl」を利用します。 psqlなどで接続出来るかを確認して下さい。
forest_ctl -D /usr/local/forest40/data start psql -p 6001
続いて2台目のクラスタDBも同様の手順でインストールを行います。
設定
環境構築ツールを用いて設定を行います。まずは環境などの設定や情報を保存しておく、グローバルシステムカタログを作成します。
cd /usr/local/forest40/bin/ ./forestadm -h 192.168.0.1 -p 6001 -g gsc -U forest -W forest -i ./forestadm -h 192.168.0.1 -p 6001 -g gsc -U forest -W forest
「-h」オプションで作成するホスト名、「-p」でポート番号、「-g」でグローバルシステムカタログのデータベース名、「-U」でスーパーユーザ名、「-W」でパスワードを指定します。 「-i」オプションをつけることでグローバルシステムカタログの初期化を行います。
作成が完了したら、環境構築ツールを用いてグローバルシステムカタログ内にログインします。
二台目のクラスタDBを追加します。「show instance」命令でインスタンスを確認出来ます。
[gsc]$ create instance 192.168.0.2 6001 ; インスタンス:192.168.0.2:6001を作成しました。 [gsc]$ show instance ; インスタンス一覧 SERVERID | HOST | PORT | STATUS ----------------------------------------- 0 | 192.168.0.1 | 6001 | 稼動中 1 | 192.168.0.2 | 6001 | 稼動中
レプリケーションを行うデータベースを作成します。
[gsc]$ create db hoge(0,1); データベース:hogeを、サーバID:0,1,に作成しました。 [gsc]$ show db; データベース一覧 DBNAME | SERVERID | HOST | PORT ------------------------------------------- hoge | 0 | 192.168.0.1 | 6001 hoge | 1 | 192.168.0.2 | 6001
「create db <データベース名>(保存するサーバのID)」命令文で作成します。サーバのIDは「show instance」で確認して下さい。
データベースに接続し、テーブルを作成します。
[gsc]$ open db hoge; [hoge]> create table test(id int, value varchar); [hoge]> show table; テーブル一覧 TABLENAME | TABLETYPE | PARTITION_FUNC | STATUS ------------------------------------------------- test | 多重化 | | 稼動中 [hoge]> close db; [gsc]$ \q;
これで環境の構築が終了しました。確認のためにpsqlなどで個々のインスタンスの「hoge」データベースに接続し、テーブル「test」が作成されているかを確認してください。
続いて、クライアントからの接続を行います。PostgresForestではpsqlなどのPostgreSQL用のクライアントで接続を行ってもレプリケーションなどの機能を実現できないため、 Jpsqlという専用のクライアントが用意されています。 「/usr/local/forest40/bin/Jpsql.sh」を実行することでクライアントを起動することが出来ます。
./Jpsql.sh -h 192.168.0.1 -p 6001 -g gsc -d hoge -U forest -W forest
「-h」オプションで接続するホスト名、「-p」でポート番号、「-g」でグローバルシステムカタログのデータベース名、「-d」データベース名、「-U」でスーパーユーザ名、「-W」でパスワードを指定します。
接続が完了したら、通常のpsqlと同様にSQL文を入力して更新を行って下さい。
[0]> insert into test values(1,'test1'); [1]> \q
更新が終了したらpsqlなどで個々のインスタンスに接続し、レプリケーションが行われているかを確認して下さい。
なお、Jpsql以外をクライアントとして利用する場合(自作のアプリケーションなど)は、PostgresForestのJDBCドライバ経由で接続する必要があります。 PostgresForestのJDBCドライバは「/usr/local/forest40/share」以下の「postgresforest40.jar」です。
起動・終了
起動・終了には前述のとおり「forest_ctl」を利用します。
cd /usr/local/forest40/bin/ 起動 ./forest_ctl -D /usr/local/forest40/data start 終了 ./forest_ctl -D /usr/local/forest40/data stop
2.4.ウォームスタンバイ
インストール
アクティブ(ホスト名:db1)とスタンバイ(ホスト名:db2)の2台のサーバを用意し、それぞれにPostgreSQL公式からダウンロードしたPostgreSQL8.2をインストールします。 なお、PostgreSQLのインストール手順については割愛させていただきます。
PostgreSQLのインストールが完了したら、アクティブ側のみ初期化を行います。
initdb -D /usr/local/pgsql/data --no-locale
設定
初期化によって出来上がったフォルダ内のpostgresql.confを開き次のように設定を行います。
vi /usr/local/pgsql/data/postgresql.conf archive_command = 'cp -i %p /net/db2/share/backup/db1/postgres/archive/%f < /dev/null' archive_timeout = 60
archive_commandでdb1からdb2へアーカイブログを転送するためのコマンドを、archive_timeoutでアーカイブログを生成する間隔を設定します。 なお、上記のarchive_commandでは、アーカイブログをNFS(autofs)でマウントされている「db2」にコピーしています。他にも「rsync」を使うなどの方法が考えられます。
PostgreSQLを起動し、データベースの構築を行います。手順は、PostgreSQLで通常に行う手順と変わりません。
pg_ctl -D /usr/local/pgsql/data -l /usr/local/pgsql/postgres.log createdb hoge psql hoge hoge=# create table test(id int, value varchar);
データベースの構築が終了したら、データベースのオンラインバックアップを行います。 オンラインバックアップでバックアップを行うことにより、PostgreSQLを起動したままバックアップを行うことができます。
オンラインバックアップの開始を宣言 hoge=# SELECT pg_start_backup('initial'); hoge=# \q PGDATAディレクトリをtarアーカイブ化 cd /usr/local/pgsql tar pgdata.tar data tarアーカイブをdb1に転送 scp data.tar db1:/usr/local/pgsql オンラインバックアップの終了を宣言 psql hoge hoge# SELECT pg_stop_backup();
スレーブ側に転送されたtarアーカイブを展開します。 展開されたディレクトリは、スレーブ側のPGDATAディレクトリとして利用しますので、適切なアクセス権がある所に展開して下さい。
cd /usr/local/pgsql tar xvf pgdata.tar
展開されたディレクトリへ移動し、スレーブ側のPGDATAディレクトリとして利用するための設定を行います。
cd data アクティブ側で使用していたPIDファイルを削除 rm portmaster.pid アーカイブログを転送する設定を解除(#をつけてコメントに) vi postgresql.conf #archive_command = 'cp -i %p /net/db2/share/backup/db1/postgres/archive/%f \ < /dev/null' #archive_timeout = 60
PGDATAディレクトリにrecovery.confを作成します。 PostgreSQLはrecovery.confに書かれた『restore_command』の実行が終了するまでリカバリモードで動作し、クライアントなどから一切の接続を受け付けません。
vi recovery.conf restore_command = '/usr/local/pgsql/data/restore.sh \ /share/backup/db1/postgres/archive/%f %p'
今回は、restore_commandの例として以下のシェルスクリプトを使用しています。 このシェルスクリプトは、アクティブ側が正常に動作している間は実行し続け、アーカイブログが転送されてくるとデータベースへの適用を行い、 アクティブ側で障害が発生するとするとシェルを終了します。 シェルが終了することにより、PostgreSQLがリカバリモードから通常モードへ移行するため、フェイルオーバを実現することができます。
#!/bin/bash FailOverTriggered="no" FailOverTriggerFile="/tmp/postgres_failover_trigger" RestoreFrom=$1 RestoreTo=$2 SleepTime=100000 # # Functions # CopyWALFileForRecovery() { cp -v -i ${RestoreFrom} ${RestoreTo} } NextWALFileReady() { if [ -f "${RestoreFrom}" ]; then return 1 else return 0 fi } CheckForExternalTrigger() { if [ -f "${FailOverTriggerFile}" ]; then return 1 else return 0 fi } NextWALFileReady while [ $? -eq 0 -a "${FailOverTriggered}" == "no" ]; do usleep ${SleepTime} CheckForExternalTrigger if [ $? -eq 1 ]; then FailOverTriggered="yes" fi NextWALFileReady done if [ "${FailOverTriggered}" == "no" ]; then CopyWALFileForRecovery fi
このシェルスクリプトでは、/tmp/postgres_failover_triggerが作成されることにより、アクティブ側の障害を検知しています。
起動・終了
PostgreSQLそのものですので、以下のコマンドで起動・終了が可能です。
起動 pg_ctl -D /usr/local/pgsql/data start 終了 pg_ctl -D /usr/local/pgsql/data stop