Heartbeat scrpits for pgpool 

1. このプログラムとは

Heartbeat 2.0以降にはCRM(Cluster Resource Manager)を使うことでサービス監視を
含むリソース管理を行ってくれるため、容易に高可用性サービスを立ち上げることが
可能になります。これとPostgreSQLのレプリケーションを実現するpgpoolを組み合わ
せることで、PostgreSQLサービスの冗長化をより簡単に行うことが出来ます。

サービス図：

                              +---------+   +----------+
                             /|[pgpool] |---|PostgreSQL|
+------+     +----------+   / +---------+   +----------+
|client| --> |Virtual IP| --             \
+------+     +----------+   \ +---------+ \ +----------+
                             \|(pgpool) |  -|PostgreSQL|
                              +---------+   +----------+


本プログラムはHeartbeatと連携してpgpoolを高可用性対応するため、以下のコードが
含まれています。

- Heartbeat 2.0以降で利用できるOCF形式のpgpool管理スクリプト
- 管理スクリプト内で使用する監視プログラム

2. インストール

このプログラムを利用するためには少なくとも２台のマシンと、それぞれに以下のものが
インストールされている必要があります。

-PostgreSQL(http://www.postgresql.org/) のクライアント
psqlのみを必要とします。インストール時に環境変数PATHで参照可能な位置に配置してください。



-perl(http://www.perl.com/)
perl 5以上とGetOpt::Longを必要とします。
-pgpool(http://pgpool.projects.postgresql.org/)
インストール時に環境変数PATHで参照可能な位置に配置してください。現段階では設定ファイルの位置は指定できないため、インストール時のデフォルト位置に配置してください。

なお、実行に当たってはpgpool.confの以下のパラメーターを利用するため、適切な

-heartbeat 2.0以降(http://www.linux-ha.org/)

また、このホストに入っている必要はありませんが、以下のソフトウェアも必要になります。

-PostgreSQL 

接続監視する関係上、pgpoolが接続する先としてのPostgreSQLサーバーが必要になります。これには、以下の条件があります。
--pgpoolが稼働しているサーバーから指定データベースへの指定ユーザーからの接続に対するtrust認証が許されていること。この時指定データベースとユーザー名は

-pgpool.confのhealth_check_userが有効な場合、ユーザー名として、また同時にdatabase名としても利用されます。標準のpgpoolの場合、nobodyなロール及びデータベースが必要です。

-有効な値がない場合、postgresユーザ/template1データベース



2.2 インストール手順

基本的なプログラム、pgpool起動と監視スクリプトは以下の通りでインストール
できます。pgpool,psqlを環境変数で参照できる形にしておいてください。

# ./configure
# cd src
# make
# make install

この時、OCF仕様のスクリプト"pgpool"が/usr/lib/orf/resource.d/heartbeat/以下に、
監視スクリプトpgpool.monitorがpgpoolと同じディレクトリにコピーされます。

2.3 heartbeatの設定
heartbeat上でpgpoolを稼働させるためにはheartbeat側の設定が必要になります。

-ha.cf
crmを利用します。以下の一行を設定してください。

crm	true

-cib.xml
cib.xmlはheartbeatでcrmを利用するために必要なファイルで、通常/var/lib/heartbeat/crm/以下に配置されています。サンプルとして1仮想IPアドレス、アクティブ/スタンバイのpgpool構成を行うcib.xmlを以下に示します。

<cib generated="true" admin_epoch="0" have_quorum="true" num_peers="2" ccm_transition="4" cib_feature_revision="1.2" crm_feature_set="1.0.4" debug_source="sync_our_cib" dc_uuid="cf40f895-0e3c-4847-b8b3-6ae1fad7921f" last_written="Mon Jul 24 07:25:00 2006" epoch="42" num_updates="1521">
   <configuration>
     <crm_config>
       <cluster_property_set id="deafult">
         <attributes>
           <nvpair id="symmetric_cluster" name="symmetric_cluster" value="true"/>
           <nvpair id="no_quorum_policy" name="no_quorum_policy" value="stop"/>
           <nvpair id="default_resource_stickiness" name="default_resource_stickiness" value="0"/>
           <nvpair id="stonith_enabled" name="stonith_enabled" value="false"/>
           <nvpair id="stop_orphan_resources" name="stop_orphan_resources" value="false"/>
           <nvpair id="stop_orphan_actions" name="stop_orphan_actions" value="true"/>
           <nvpair id="remove_after_stop" name="remove_after_stop" value="false"/>
           <nvpair id="short_resource_names" name="short_resource_names" value="true"/>
           <nvpair id="transition_idle_timeout" name="transition_idle_timeout" value="5min"/>
           <nvpair id="is_managed_default" name="is_managed_default" value="true"/>
         </attributes>
       </cluster_property_set>
     </crm_config>
     <nodes>
       <node id="cf40f895-0e3c-4847-b8b3-6ae1fad7921f" uname="node1" type="normal"/>
       <node id="3e919e96-e476-4d3e-be05-0048b9e12a56" uname="node2" type="normal"/>
     </nodes>
     <resources>
       <group id="group_1">
         <primitive class="ocf" id="IPaddr_1" provider="heartbeat" type="IPaddr">
           <operations>
             <op id="IPaddr_1_mon" interval="5s" name="monitor" timeout="5s"/>
           </operations>
           <instance_attributes>
             <attributes>
               <nvpair id="IPaddr_1_attr_0" name="ip" value="192.168.0.3"/>
             </attributes>
           </instance_attributes>
         </primitive>
         <primitive class="ocf" id="pgpool_2" provider="heartbeat" type="pgpool">
           <operations>
             <op id="pgpool_2_mon" interval="30s" name="monitor" timeout="20s"/>
           </operations>
         </primitive>
       </group>
     </resources>
     <constraints>
       <rsc_location id="rsc_location_group_1" rsc="group_1">
         <rule id="prefered_location_group_1" score="100">
           <expression attribute="#uname" id="prefered_location_group_1_expr" operation="eq" value="node1"/>
         </rule>
       </rsc_location>
     </constraints>
   </configuration>
 </cib>

この設定ファイル例によりpgpoolを管理できるようになります。この中で書き換える項目は以下の通りになります。

-ノード名
　サンプル中node1,node2と示されているのがノード名になります。ここではha.cfで指定してあるファイルと同じ名称を指定してください。

-IPアドレス
　サンプル中で192.168.0.3と示されているのが仮想IPアドレスです。ここに指定することでpgpoolが稼働中のホストに当該IPアドレスが割り振られます。


　この記述が終了したらファイルをheartbeatが利用する全てのサーバーに配置します。cib.xmlはサーバー間で全く同じである必要があります。なお、記述の検証にはheartbeatに付属しているcrm_verifyコマンドが使えます。

crm_verify -VX /opt/powergres/hb/var/lib/heartbeat/crm/cib.xml

　最後に全てが終わったら起動して確認します。

# service heartbeat start

そのあとheartbeat自体の起動が終了まで数分待ち、psにてpgpoolが起動することを確認することが出来れば完了です。

3. 利用方法

本ソリューションの起動及び終了はheartbeat経由で自動で行われます。順序としては以下の通りになります。

- PostgreSQLを起動

pgpoolで利用するPostgreSQLを起動します。

- heartbeatを起動

heartbeatを起動します。起動する場合はサービスとして

#service heartbeat start

と利用します。しばらくするとpgpoolが利用可能になります。この後、psql等で接続するためにはcib.xmlで指定したIPアドレスとpgpoolで指定したポートを指定します。例えば先ほどのサンプルの場合

psql -h 192.168.0.3 -p 9999

と実行すれば接続できます。

終了させる場合は、全く逆に全てのサーバーでheartbeatを終了させてください。heartbeatの終了のためには以下の通りのコマンドを実行します。

# service heartbeat stop

4. FAQ

-接続できない
以下の項目を確認してください。

--heartbeatが起動しているか。

起動していない場合、heartbeatのインストールか設定ファイルに問題があります。

--heartbeatが起動していて、psの出力の中にcrmdが存在しているか

crmdが立ち上がってない、終了した場合にはcib.xmlファイルの内容にエラーがある可能性があります。特に前回実行時の内容を署名していますので、.sigファイルが当該ディレクトリに存在している場合にはエラーになります。そのため、書き換えた場合には*.sigファイルを消去し、再度実行してみてください。

--pgpoolが起動しているか。

起動していない場合、pgpoolが単独で実行できるかどうかを確認してください。また、設定ファイルの内容も確認して下さい。

--PostgreSQLが起動しているか。

起動していない場合は立ち上げてください。

--浮動IPに対してping等でアクセスできるか。

アクセスできない場合には設定ファイルを再度確認してください。


なお、一度全てのホストでheartbeatを終了/起動させることで実行できることがあります。

-PGClusterのロードバランサーの冗長化に使えるか？
技術的には可能ですが、現在その設定に必要な内容が不足しているため、利用することは出来ません。このためには以下の作業が必要です。

--pgpoolファイルを書き換え、pglbを起動終了させるようにする
--pgpoolファイルを書き換え、設定ファイル無しにポート番号等を指定するようにする。


5. 制限事項
・本プログラムに置ける監視はpgpoolの稼働チェック(pidファイルとSQL発行)のみです。
それ以外の異常状態（起動して、SQL文も受け付けるが異常が発生しているような場合など）には対応できません。
・PostgreSQL に対する管理は行っていません。
・PostgreSQL が全く起動していない状態は異常であるとみなし、フェイルオーバーし続けますが、これは現段階の仕様です。
・PostgreSQL がクラッシュした場合のリカバリは別途手動で行う必要があります。この方法についてはpgpoolに準じます。
・ロックの問題、now()関数、OIDといったpgpoolの技術的制限事項が解消するわけ
ではありません。

6. 著作権
本プログラムは谷田　豊盛（ゆたか） (tanida@sraoss.co.jp)が作成しました。著作権はいわゆるBSDライセンスライクなものとします。詳細は付属のCOPYINGファイルを参照ください。


