このチュートリアルでは watchdog 機能を使用して、2台の PostgreSQL を2台の pgpool-II で共有する方法について説明します。
Linux マシン 2 台にそれぞれ、PostgreSQL(9.3 以降)と pgpool-II(3.3 以降)がインストールされている構成とします。サーバ名は「osspc19」「osspc20」とします。また psql などを実行するサーバを便宜上「someserver」と表記していますが、osspc19、osspc20 の何れかのサーバ、あるいは他のサーバでも構いません。
PostgreSQL を 2 台のサーバにインストールし、Hot Standby / Streaming Replication 構成に設定しておきます。最初のプライマリサーバを osspc19、スタンバイサーバを osspc20 とします。
その方法についてはここでは説明しません。PostgreSQL のドキュメントを参照にして設定を行ってください。
master-slave モードの設定をしておきます。同期モードはストリーミングレプリケーションです。
master_slave_mode = on # Activate master/slave mode # (change requires restart) master_slave_sub_mode = 'stream' # Master/slave sub mode # Valid values are combinations slony or # stream. Default is slony. # (change requires restart)
それ以外の、バックエンド, failover_command, recovery_1st_stage の設定、pgpool_remote_start の配置などを適切に行ってください。
以下は今回使用した設定ファイル、スクリプトのサンプルです。
ファーストステージ用のスクリプトの中で PostgreSQL 9.1 から提供された pg_basebackup を利用しているので、ここでは PostgreSQL 9.1 以上を前提にしていますが、rsync などを使って 9.0 以前のバージョンの PostgreSQL を利用することもできます。
それ以外の pgpool-II 基本設定について説明します。osspc19, osspc20 で共通です。
pgpool-II で使用するポートはデフォルト値を用います。
port = 9999 # Port number # (change requires restart)
ロードバランスを有効にしておきます。
load_balance_mode = on # Activate load balancing mode # (change requires restar
自動 failover のため、ヘルスチェックを有効にします。
health_check_period = 5 # Health check period # Disabled (0) by default health_check_timeout = 0 # Health check timeout # 0 means no timeout health_check_user = 'postgres' # Health check user
watchdog を有効にします。
use_watchdog = on # Activates watchdog
まだ使われていない IP アドレスを記述してください。
delegate_IP = '192.168.1.101' # delegate IP address
自分が稼働するサーバのホスト名を記述します。
(osspc19) wd_hostname = 'osspc19' # Host name or IP address of this watchdog
(osspc20) wd_hostname = 'osspc20' # Host name or IP address of this watchdog
watchdog で使用するポートはデフォルトのままにしておきます。
wd_port = 9000 # port number for watchdog service
仮想 IP の制御につかうコマンドのパスを設定します。本チュートリアルでは /home/apache/sbin を設定します。理由は後述します。
ifconfig_path = '/home/apache/sbin' # ifconfig command path arping_path = '/home/apache/sbin' # arping command path
watchdog の死活監視方法を選択します。ここでは pgpool-II 3.3 で新たに追加された死活監視方法の、ハートビートを設定します。
wd_lifecheck_method = 'heartbeat' # Method of watchdog lifecheck ('heartbeat' or 'query') # (change requires restart)
watchdog の死活監視の間隔を指定します。ここではデフォルトより短めの 3 秒に設定します。
wd_interval = 3 # lifecheck interval (sec) > 0
ハートビート信号を受信するポート番号「wd_heartbeat_port」、ハートビート信号の送信対象となるホスト名「heartbeat_destination0」、そのポート番号「heartbeat_destination_port0」を、それぞれ設定します。
(osspc19) wd_heartbeat_port = 9694 # Port number for receiving heartbeat signal # (change requires restart) heartbeat_destination0 = 'osspc20' # Host name or IP address of destination 0 # for sending heartbeat signal. # (change requires restart) heartbeat_destination_port0 = 9694 # Port number of destination 0 for sending # heartbeat signal. Usually this is the # same as wd_heartbeat_port. # (change requires restart)
(osspc20) wd_heartbeat_port = 9694 # Port number for receiving heartbeat signal # (change requires restart) heartbeat_destination0 = 'osspc19' # Host name or IP address of destination 0 # for sending heartbeat signal. # (change requires restart) heartbeat_destination_port0 = 9694 # Port number of destination 0 for sending # heartbeat signal. Usually this is the # same as wd_heartbeat_port. # (change requires restart)
監視対象とする pgpool-II が稼働する ホスト名「other_pgpool_hostname0」、その pgpool-II のポート番号「other_pgpool_port0」、その watchdog のポート番号「other_wd_port0」を、それぞれで記述します。
(osspc19) other_pgpool_hostname0 = 'osspc20' # Host name or IP address to connect to for other pgpool 0 other_pgpool_port0 = 9999 # Port number for othet pgpool 0 other_wd_port0 = 9000 # Port number for othet watchdog 0
(osspc20) other_pgpool_hostname0 = 'osspc19' # Host name or IP address to connect to for other pgpool 0 other_pgpool_port0 = 9999 # Port number for othet pgpool 0 other_wd_port0 = 9000 # Port number for othet watchdog 0
本チュートリアルでは pgpoolAdmin を使って説明を行います。pgpoolAdmin を osspc19, osspc20 それぞれにインストールしてください。インストール方法についてはここでは説明しません。pgpoolAdmin のマニュアルを参照してください。
watchdog 内部で行う仮想 IP の制御には root の権限が必要です。pgpool-II 自体を root ユーザで実行する方法もありますが、ここでは pgpoolAdmin を使用するため apache ユーザから 仮想 IP の制御ができる必要があります。そのため、 ifconfig, arping に setuid を設定します。また、セキュリティ上の理由から apache ユーザ以外はこれらのコマンドにアクセスできないようにしておきます。以下を、osspc19, osspc20 の両サーバで以下を実行してください。(この操作には root 権限が必要です。)
まず setuid が設定された ifconfig, arping を格納する専用のディレクトリ(ifconfig_path, arping_path に設定したもの。ここでは /home/apache/sbin )を作成し、apache ユーザのみに実行権限を与えます。
$ su - # mkdir -p /home/apache/sbin # chown apache:apache /home/apache/sbin # chmod 700 /home/apache/sbin
次にそのディレクトリへ ifconfig, arping をコピーし、setuid を設定します。
# cp /sbin/ifconfig /home/apache/sbin # cp /usr/sbin/arping /home/apache/sbin # chmod 4755 /home/apache/sbin/ifconfig # chmod 4755 /home/apache/sbin/arping
ただし、以上の方法は本チュートリアル向けの簡易なものです。実際の運用では ifconfig, arping を内部で実行する wrapper プログラムを作成し、それに setuid を設定するのがより良い方法です。しかし、これは本チュートリアルの主旨では無いので、ここで詳しくは説明しません。
両サーバで PostgreSQL が起動済みであることを前提とします。
pgpool-II を起動する前に、ログ取得のための設定をします。「pgpoolAdmin設定」画面で非デーモンモード(-n)にチェックを入れて「更新」ボタンをクリックしてください。
その後「pgpool ステータス」画面より、occpc19, osspc20 の順番で pgpool-II を起動します。非デーモンモード(-n) にチェックが入っていることを確認して「pgpool起動」ボタンをクリックします。
pgpool-II 起動後に現れる以下の「ログ」ボタンをクリックすることで、ログを確認することができます。
死活監視が始まり watchdog の準備が整うと、ログに以下のメッセージが出力されます。今回の設定では少なくとも 30 秒程度かかります。(wd_interval の設定に依存します。)
2014-04-04 22:15:54 LOG: pid 5912: wd_init: start watchdog ... 2014-04-04 22:16:55 LOG: pid 5923: watchdog: lifecheck started
仮想 IP アドレスを用いて PostgreSQL に接続できることを確認します。
(someserver) $ psql -h 192.168.1.101 -p 9999 -l
先に起動した osspc19 で仮想 IP が立ち上がっており、pgpool-II は Active として起動しています。
(osspc19) $ /sbin/ifconfig | grep eth0:0 -1 eth0:0 Link encap:Ethernet HWaddr 00:1E:C9:xx:xx:xx inet addr:192.168.1.101 Bcast:192.168.1.255 Mask:255.255.254.0
一方、osspc20 では仮想 IP が使われておらず、pgpool-II は Standby として起動しています。
(osspc20) $ /sbin/ifconfig | grep eth0:0 -1 -- 出力なし --
Active の pgpool-II が停止した場合には、Standby が新しい Active として仮想 IP を引き継ぎます。
osspc19 の pgpoolAdmin の「pgpool停止」ボタンから pgpool-II を停止します。
osspc20 で仮想 IP が立ち上がったことを確認します。
(osspc20) $ /sbin/ifconfig | grep eth0:0 -1 eth0:0 Link encap:Ethernet HWaddr 00:1E:C9:xx:xx:xx inet addr:192.168.1.101 Bcast:192.168.1.255 Mask:255.255.254.0
PostgreSQL への接続は同じ仮想 IP が使用ができます。
(someserver) $ psql -h 192.168.1.101 -p 9999 -l
osspc19 の pgpoolAdmin から pgpool-II を起動してください。
ここで再起動された pgpool-II は Standby となり、osspc19 では仮想 IP は立ち上がらないことを確認します。
(osspc19) $ sudo bin/pgpool -n > pgpool.log 2>&1 -- 出力なし --
ここまでの watchdog の振る舞いはバックエンドが1台の場合とまったく同じです。
複数の PostgreSQL を共有している場合には、watchdog は pgpool-II 間で DBノード状態の同期をとります。具体的には、ある pgpool-II で failover command(ノードの追加、切り離しなど)が実行された場合、他の全ての pgpool-II で同じコマンドが実行されます。
pgpoolAdmin で、現在のノード状態を確認します。 この段階では、osspc19, osspc20 ともに両ノードが稼働中であることが分かります。
ここで Primary DB である osspc19 の PostgreSQL をダウンさせます。
(osspc19) $ pg_ctl stop -m i
failover が実行され、osspc20 の PostgreSQL が新たな Primary となります。
各 pgpool-II のログに以下のように出力されます。
2014-04-04 23:00:57 LOG: pid 6680: failover: set new primary node: 1 2014-04-04 23:00:57 LOG: pid 6680: failover: set new master node: 1 ... 2014-04-04 23:00:57 LOG: pid 6680: failover done. shutdown host osspc19(5432)
両方の pgpoolAdmin から osspc19 のノードがダウンしたことが確認できます。
どちらかの pgpoolAdmin で「リカバリ」ボタンを押し、osspc19 のノードをオンラインリカバリします。 ここでは osspc19 の pgpoolAdmin からオンラインリカバリを行うことにします。
オンラインリカバリが終了すると、各 pgpool-II のログに以下のように出力され、osspc19 が復帰したことがわかります。
2014-04-04 23:18:30 LOG: pid 6680: failover: set new primary node: 1 2014-04-04 23:18:30 LOG: pid 6680: failover: set new master node: 0 2014-04-04 23:18:30 LOG: pid 6680: failback done. reconnect host osspc19(5432)
osspc19 のノードが今度はスタンバイとして稼働し始めたことが、両方の pgpoolAdmin から確認できます。
これでバックエンドの Primary と Secondary が最初の状態から入れ替わったことになります。これは pgpool-II から見ると、INSERT クエリの送り先が変わったことを意味しています。しかし、2 つの pgpoolAdmin が同じ情報を示していることから分かるように、このノードの状態の情報は pgpool-II 間で共有されています。そのため、Active/Standby が入れ替わり、クエリを処理する pgpool-II が変更されたとしても、 バックエンドへのアクセスは問題なく行うことができます。
現在の Active である osspc20 の pgpool-II を pgpoolAdmin から再起動させてください。すると osspc19 の pgpool-II が新しい Active になります。
仮想 IP を使ってデータの読み書きが正しく行えることを確認します。
(someserver) $ psql -h 192.168.1.101 -p 9999 -c "INSERT INTO test VALUES (123)" INSERT 0 1 (someserver) $ psql -h 192.168.1.101 -p 9999 -c "SELECT * FROM test" i ---- 123 (1 row)
最後にサーバ全体がダウンしたときの挙動を確かめます。再び osspc20 の pgpool-II を Active にするため、osspc19 の pgpool-II を再起動してください。そうすると、osspc20 の pgpool-II は Active, PostgreSQL は Primary になっているはずです。
(osspc20) $ /sbin/ifconfig | grep eth0:0 -1 eth0:0 Link encap:Ethernet HWaddr 00:1E:C9:xx:xx:xx inet addr:192.168.1.101 Bcast:192.168.1.255 Mask:255.255.254.0
その状態から osspc20 のサーバをシャットダウンします。
(osspc20) $ su - (osspc20) # shutdown now
しばらく待つと pgpool-II が osspc20 サーバのダウンを検出し、以下のように osspc19 の PostgreSQL が Primary に、pgpool-II が Active に昇格します。
(osspc19) $ /sbin/ifconfig | grep eth0:0 -1 eth0:0 Link encap:Ethernet HWaddr 00:1E:C9:xx:xx:xx inet addr:192.168.1.101 Bcast:192.168.1.255 Mask:255.255.254.0