1.5. フェイルオーバを試してみる

PostgreSQLサーバが停止した際に、Pgpool-IIは自動フェイルオーバさせることができます。 この場合、Pgpool-IIはステータスを"down"にして、残ったサーバでデータベースの運用を継続します。

$ pg_ctl -D data1 stop
waiting for server to shut down.... done
server stopped
$ psql -p 11000 -c "show pool_nodes" test
 node_id | hostname | port  | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay 
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------
 0       | /tmp     | 11002 | up     | 0.500000  | primary | 2172       | true              | 0
 1       | /tmp     | 11003 | down   | 0.500000  | standby | 0          | false             | 0
(2 rows)

$ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test
  sum   
--------
 192112
(1 row)
      

スタンバイノードをpg_ctlコマンドで停止しました。 Pgpool-IIはそのことを検出し、そのスタンバイノードを切り離します。 "show pool_nodes"コマンドは、スタンバイノードがダウンしていることを表示します。 このスタンバイノードなしで、クラスタの運用を継続できます。

$ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test
  sum   
--------
 192112
(1 row)
      

プライマリサーバが落ちたらどうなるでしょう? この場合、残ったスタンバイサーバの一つが新しいプライマリサーバへと昇格します。 テストのため、両方のノードが稼働中である状態から始めます。

$ psql -p 11000 -c "show pool_nodes" test
 node_id | hostname | port  | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay 
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------
 0       | /tmp     | 11002 | up     | 0.500000  | primary | 2173       | true              | 0
 1       | /tmp     | 11003 | up     | 0.500000  | standby | 0          | false             | 0
(2 rows)

$ pg_ctl -D data0 stop
waiting for server to shut down.... done
server stopped
$ psql -p 11000 -c "show pool_nodes" test
 node_id | hostname | port  | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay 
---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------
 0       | /tmp     | 11002 | down   | 0.500000  | standby | 2173       | false             | 0
 1       | /tmp     | 11003 | up     | 0.500000  | primary | 0          | true              | 0
(2 rows)
      

プライマリノードが0から1へと変わりました。 内部では何が起きたのでしょう? ノード0がダウンした時、Pgpool-IIはそのことを検出し、pgpool.confに定義された"fail_over_script"を実行します。 その内容を以下に示します。

#! /bin/sh
# Execute command by failover.
# special values:  %d = node id
#                  %h = host name
#                  %p = port number
#                  %D = database cluster path
#                  %m = new master node id
#                  %M = old master node id
#                  %H = new master node host name
#                  %P = old primary node id
#                  %R = new master database cluster path
#                  %r = new master port number
#                  %% = '%' character
failed_node_id=$1
failed_host_name=$2
failed_port=$3
failed_db_cluster=$4
new_master_id=$5
old_master_id=$6
new_master_host_name=$7
old_primary_node_id=$8
new_master_port_number=$9
new_master_db_cluster=${10}
mydir=/home/t-ishii/tmp/Tutorial
log=$mydir/log/failover.log
pg_ctl=/usr/local/pgsql/bin/pg_ctl
cluster0=$mydir/data0
cluster1=$mydir/data1

date >> $log
echo "failed_node_id $failed_node_id failed_host_name $failed_host_name failed_port $failed_port failed_db_cluster $failed_db_cluster new_master_id $new_master_id old_master_id $old_master_id new_master_host_name $new_master_host_name old_primary_node_id $old_primary_node_id new_master_port_number $new_master_port_number new_master_db_cluster $new_master_db_cluster" >> $log

if [ a"$failed_node_id" = a"$old_primary_node_id" ];then	# master failed
! 	new_primary_db_cluster=${mydir}/data"$new_master_id"
	echo $pg_ctl -D $new_primary_db_cluster promote >>$log	# let standby take over
	$pg_ctl -D $new_primary_db_cluster promote >>$log	# let standby take over
fi
      

そのスクリプトは、パラメータとして必要な情報をPgpool-IIから受け取ります。 プライマリサーバが落ちた時に、"pg_ctl -D data1 promote"を実行し、スタンバイサーバは新しいプライマリサーバへと昇格します。