サイト内の現在位置

PostgreSQL

Pgpool-II を用いた自動フェイルオーバーの実現方法

本ページでは、Pgpool-II を用いた自動フェイルオーバーの実現方法について解説します。
具体的な設定手順と動作確認の流れをご紹介していきますので、ぜひ最後までご覧ください。

①Pgpool-II の概要とメリット

Pgpool-II とは、PostgreSQLのpool(=PostgreSQLのプロセス)を管理する事により
以下の機能を提供するクラスタ制御系ソフトウェアです。
主な機能とそのメリットは、以下のページで解説していますのでご覧下さい。

Pgpool-II 機能紹介

②Pgpool-II に関する重要なキーワード解説

その1:スプリットブレイン
クラスタが分断された時に、プライマリノードが複数存在してしまう状態の事を指します。

  • この状態でDDL等のクエリが発行されて更新がかかると、データの整合性が損なわれてしまう恐れがあります。
    また、仮想IPが複数起動してしまい、IPアドレスが重複してしまう恐れもあります。(図1)
  • 基本的に、スプリットブレインはネットワーク障害やパラメータの設定ミス、
    スクリプトの記載ミスが原因で引き起こされます。
    対処法としては、後述する「クォーラム」が挙げられます。
    たとえ特定のノードで障害が起きたり、ノード間のネットワークで障害が起きても3台以上の構成であれば、
    多数決による合意形成で過半数を取らなければフェイルオーバーは行われず、
    スプリットブレインは起こりません。(図3)

その2:クォーラム(quorum)
アルゴリズムの1つで、分散システムにおいてデータの一貫性や可用性を維持するために、
データの読み書き等を実行する際に合意形成を行う必要のある最小ノード数の事を指します。

  • 今回の場合だと、フェイルオーバーを安全にするための Pgpool-II ノード間の多数決会議を指します。(図3)
    可用性においては、以下のケースにおいて、Watchdogクラスタでクォーラム確認と合意形成を行います。

  ①バックエンド(PostgreSQLサーバー)でのフェイルオーバー実行前
  ②Pgpool-II サーバー側でリーダーノードを選定する際
  ③仮想IPの保持、引継ぎの際

  • リーダーに選出されたPgpool-II ノードだけが、実際のfailover_commandを実行する事が出来ます。
  • failover_when_quorum_exists = on にすると、Pgpool‑II が「他の Pgpool‑II と合意(クォーラム)」ができた場合にのみフェイルオーバーを発火させ、誤検知による無用な昇格を抑止する事が可能です。
  • クォーラムが存在しない場合は、Watchdogが仮想IPを特定のノードに上げる事はないが、
    OSレベルで手動で付与する事は可能です。
    その際、ip addr addとarpingコマンドを使用して、ネットワークインターフェースに
    新たに仮想IPを記載します。
  • enable_consensus_with_half_votes = on にすると、偶数台のノードでもクォーラム投票を行う事が
    出来るようになるがスプリットブレインの発生確率が大きく上がります。

図1:スプリットブレインのイメージ(2台構成の場合)
図2:スプリットブレインのイメージ(3台構成の場合)
図3:クォーラムのイメージ(Pgpool-II とPostgreSQLサーバーの場合)

③実際の設定手順と動作確認

環境情報

今回の検証における動作環境は以下の通りです。
奇数台の投票を原則とするため、3台構成とします。
ストリーミングレプリケーションを行うので、各マシンでインストールする
PostgreSQLのメジャーバージョンは16で一致させます。
Linux、Pgpool-II のメジャーバージョンも合わせておくと安心です。
また、Pgpool-II サーバーとPostgreSQLサーバーが同一サブネット内にあり、
かつクラスター構成である事を前提とします。

プライマリサーバー
  IPアドレス:172.16.7.201
  ホスト名:Server1
  バージョン:RHEL8.10、PostgreSQL16.10、pgpool-II version4.6.4
スタンバイサーバー(1台目)
  IPアドレス:172.16.7.211
  ホスト名:Server2
  バージョン:RHEL8.40、PostgreSQL16.10、pgpool-II version4.6.4
スタンバイサーバー(2台目)
  IPアドレス:172.16.7.212
  ホスト名:Server3
仮想IP:172.16.7.203

前提条件

  • $PGDATAは、/home/postgres/pgdata/pg16_3です。
  • PostgreSQLのホームディレクトリは、3台ともvar/lib/pgsqlです。
  • レプリケーションスロットは無効とします。
  • 公開鍵認証方式を用いて、あらかじめSSH認証を自動化設定を行います。
  • ポートの占有を確実に防ぐため、ファイアウォールは無効化します。


※補足
 レプリケーションスロットとは:
  未取得のWALをプライマリが削除しないように保証する仕組みです。
  →無効化すると、WAL肥大化によるディスク容量圧迫リスクを回避出来ます。
   ただし、WALの取りこぼしが発生する可能性があります。

全体の流れ

1. 事前準備
  1.1. PostgreSQL, Pgpool-II のインストール   
2. サーバーセットアップ
  2.1. プライマリサーバーのセットアップ
  2.2. スタンバイサーバーのセットアップ
  2.3. PostgreSQLユーザーの作成
  2.4. .pgpassの作成
3. ストリーミングレプリケーション構築
  3.1. 手動レプリケーションの構築
4. Pgpool-II 関連設定
  4.1. PCP接続認証の設定
  4.2. pgpool_node_idファイルの作成
  4.3. Pgpool-II の設定
  4.4. クライアント認証設定
  4.5. Watchdog設定
  4.6. ログの設定
  4.7. 別サーバーへの各種設定ファイルの転送
5. 動作確認
  5.1. 各ノードの状態確認
  5.2. Pgpool-II サーバー、仮想IPのフェイルオーバーの確認
  5.3. PostgreSQLサーバー(バックエンド)のフェイルオーバーの確認

1. 事前準備

1.1. PostgreSQL, Pgpool-II のインストール

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

各サーバーに、PostgreSQLとPgpool-II をそれぞれ各々でインストールしておいて下さい。

2. サーバーセットアップ

2.1. プライマリサーバーのセットアップ

対象サーバー:172.16.7.201

プライマリサーバー(Server1)上でinitdbコマンドを実行して、DBクラスタの初期化を行います。

$ su - postgres
$ /usr/pgsql-16/bin/initdb --no-locale -E UTF8 -D /home/postgres/pgdata/pg16_3

設定ファイル$PGDATA/postgresql.confを以下のように編集する。 pg_rewindを使うためにwal_log_hintsを有効にします。

listen_addresses = '*'
wal_log_hints = on

※補足
 pg_rewindとは:
 分岐したタイムライン差分同期ツール
 wal_log_hintsを有効にする事で、全てのページ変更情報がWALに書き出されるようになるため、
 pg_rewindが正しく差分を検出出来るようになる。デフォルトはoffです。

2.2. スタンバイサーバーのセットアップ

対象サーバー:172.16.7.211、172.16.7.212

スタンバイサーバー(Server2, Server3)上でpg_basebackupコマンドを実行し、
プライマリデータベースのバックアップを作成する。

pg_basebackup -h 172.16.7.201 -p 5432 -U repl_user -D $PGDATA -Fp -Xs -P

Server2上の$PGDATA配下にmyrecovery.confファイルを作成し、中身に下記の内容を記述します。
Server3に関しても同様に設定を行います。

$ primary_conninfo = 'host=172.16.7.201 port=5432 user=repl_user application_name=172.16.7.211 passfile=''/var/lib/pgsql/.pgpass'''
recovery_target_timeline = 'latest'

*hostにはプライマリサーバーのIPアドレスを記入します。
*application_nameには、各サーバーのIPアドレスを記入します。
*passfileには、.pgpassのパスを記入します。

postgresql.confの中に、上記のmyrecovery.confへのパスを記載します。

$ vi $PGDATA/postgresql.conf
  include=/home/postgres/pgdata/pg16_3/myrecovery.conf

*デフォルトでは、後述するフェイルオーバー関連スクリプトのリカバリファイルがpostgresql.confになっています。
 そのため、postgresql.confの中にリカバリ専用ファイルへのパスを記入する事で、管理を簡単にする事が可能です。

Server2の$PGDATA配下に、standby.signalファイルを作成し、スタンバイサーバーとして起動出来るようにします。
Server3についても同様に作成します。

$ touch $PGDATA/standby.signal

Server2を起動します。
Server3についても同様に起動します。

$ pg_ctl -D $PGDATA start

2.3. PostgreSQLユーザーの作成

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

各サーバー上で、強固な安全性とリスク低減能力を持つ、scram-sha-256認証を設定します。
password_encryption = 'scram-sha-256'に変更してから、ユーザを登録します。

以下の3つのユーザーを作成し、適切な権限設定とパスワード設定を行います。

ユーザー名 パスワード 備考
reple_user repl PostgreSQLのレプリケーション専用ユーザー。
pgpool pgpool Pgpool-II のレプリケーション遅延チェック(sr_check_user)とヘルスチェック専用ユーザー(health_check_user)。
postgres postgres スーバーユーザー権限を持った予備ユーザー。

2.4. .pgpassの作成

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

各サーバー上でパスワード入力なしで、ストリーミングレプリケーションやpg_rewindを行うために、
postgresユーザーのホームディレクトリ(var/lib/pgsql)に.pgpassを作成し、
適切な権限(600)を設定します。

3. ストリーミングレプリケーション構築

3.1. 手動レプリケーションの構築

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

Server1上で、WALアーカイブ保存用の専用ディレクトリを作成します。

$ mkdir -p /home/postgres/repl_wal-archive

Server1上で、以下のようにパラメータを設定します。

# postgresql.conf

listen_addresses = '*'
wal_level = replica
max_wal_senders = 4
max_connections = 100
wal_keep_size = '4GB'
wal_sender_timeout = 120s
synchronous_commit = 'local'
archive_mode = on
archive_command = 'cp %p /home/postgres/repl_wal-archive/%f'

#pg_hba.conf

host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     repl_user       172.16.7.201/32         scram-sha-256
host    replication     repl_user       172.16.7.211/32         scram-sha-256
host    replication     repl_user       172.16.7.212/32         scram-sha-256

Server2上で、以下のようにパラメータを設定します。
Server3についても同様にパラメータ設定を行います。

# postgresql.conf

listen_addresses = '*'
wal_level = replica
max_wal_senders = 4
max_connections = 100
wal_keep_size = '4GB'
wal_sender_timeout = 120s
synchronous_commit = 'local'
archive_mode = on
archive_command = 'cp %p /home/postgres/repl_wal-archive/%f'

hot_standby = on
wal_receiver_timeout = 60s

#pg_hba.conf

host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     repl_user       172.16.7.201/32         scram-sha-256
host    replication     repl_user       172.16.7.211/32         scram-sha-256
host    replication     repl_user       172.16.7.212/32         scram-sha-256

Server1上のDBサーバーにログインし、レプリケーション状態を確認します。

$ psql -d repl_user -U repl_db
repl_db=# SELECT * FROM pg_stat_replication;

-[ RECORD 1 ]----+------------------------------
pid              | 4152917
usesysid         | 28782
usename          | repl_user
application_name | walreceiver
client_addr      | 172.16.7.211
client_hostname  |
client_port      | 41908
backend_start    | 2025-12-16 03:32:31.161518-05
backend_xmin     |
state            | streaming
sent_lsn         | 1/40652BA0
write_lsn        | 1/40652BA0
flush_lsn        | 1/40652BA0
replay_lsn       | 1/40652BA0
write_lag        | 00:00:00.000677
flush_lag        | 00:00:00.001723
replay_lag       | 00:00:00.002005
sync_priority    | 0
sync_state       | async
reply_time       | 2025-12-16 03:57:27.394475-05
-[ RECORD 2 ]----+------------------------------
pid              | 4153041
usesysid         | 28782
usename          | repl_user
application_name | walreceiver
client_addr      | 172.16.7.212
client_hostname  |
client_port      | 58788
backend_start    | 2025-12-16 03:33:08.511931-05
backend_xmin     |
state            | streaming
sent_lsn         | 1/40652BA0
write_lsn        | 1/40652BA0
flush_lsn        | 1/40652BA0
replay_lsn       | 1/40652BA0
write_lag        | 00:00:00.000675
flush_lag        | 00:00:00.001501
replay_lag       | 00:00:00.001821
sync_priority    | 0
sync_state       | async
reply_time       | 2025-12-16 03:57:26.621997-05

*プライマリサーバー上で上記のようにreplicationが表示出来れば、
 スタンバイサーバー上でpg_stat_wal_receiverをSELECTする必要はありません。

4. Pgpool-II 関連設定

4.1. PCP接続認証の設定

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

Pgpool-II インストール時のデフォルトのパスを、/home/postgres/配下にコピーします。

$ cp -r /etc/pgpool-II /home/postgres/

pg_md5を用いて、PCPユーザーのパスワードを暗号化し、「username:encryptedpassword」という形で、
pcp.confに記載します。

$ pg_md5 pgpool_password
pgpool:4aa0cb9673e84b06d4c8a848c80eb5d0

$ sudo vi /home/postgres/pgpool-II/pcp.conf
   ・
   ・
# USERID:MD5PASSWD
pgpool:4aa0cb9673e84b06d4c8a848c80eb5d0

follow_primary.shのスクリプトでパスワード入力なしでPCPコマンドを実行するために、
Pgpool-II の起動ユーザ(postgresユーザ)のホームディレクトリに.pcppassを作成します。
適切な権限設定も行います。

$ sudo vi ./.pcppass

localhost:9898:pgpool:pgpool_password

$ chmod 600 ~/.pcppass

scpで他のサーバーにも.pcppassを転送します。

$ sudo scp -i ~/.ssh/id_rsa_pgpool -p ~/.pcppass postgres@172.16.7.211:
  sudo scp -i ~/.ssh/id_rsa_pgpool -p ~/.pcppass postgres@172.16.7.212:

*下記のファイルの違いについて把握しておきましょう。
pgpool.conf:Pgpool-II の「動作設定」
pcp.conf:Pgpool-II の「管理者認証情報(暗号化)」
.pgpass:PostgreSQL接続の「パスワード自動入力(平文)」
.pcppass:PCPコマンドの「パスワード自動入力(平文)」

4.2. pgpool_node_idファイルの作成

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

Watchdog機能によって、どの設定がどのホストであるかを区別するために、
各サーバー上でpgpool_node_idファイルにpgpool(watchdog)ホストを識別するための
ノード番号(0、1、2など)を追加します。

始めに、172.16.7.201上で、pgpool_node_idファイルを編集します。

$ sudo vi /home/postgres/pgpool-II/pgpool_node_id

0

他サーバー(Server1, Server2)上でも同様に、pgpool_node_idファイルにpgpool(watchdog)ホストを
識別するためのノード番号(1、2)をそれぞれpgpool_node_id追加します。
*ファイルの中身は、単一の数字のみを記述します。

4.3. Pgpool-II の設定

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

/home/postgres/pgpool-II/配下にあるpgpool.confを以下のように編集し、
自動フェイルオーバーを実行するためのヘルスチェック設定を行います。

# ヘルスチェック設定
listen_addresses = '*'
pcp_listen_addresses = '*'
port = 9999
sr_check_user = 'pgpool'
sr_check_password = ''
health_check_period = 5
health_check_timeout = 30
health_check_user = 'pgpool'
health_check_password = ''
health_check_max_retries = 3

# バックエンド設定
backend_hostname0 = '172.16.7.201'
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/home/postgres/pgdata/pg16_3'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_application_name0 = '172.16.7.201'
backend_hostname1 = '172.16.7.211'
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/home/postgres/pgdata/pg16_3'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_application_name1 = '172.16.7.211'

backend_hostname2 = '172.16.7.212'
backend_port2 = 5432
backend_weight2 = 1
backend_data_directory2 = '/home/postgres/pgdata/pg16_3'
backend_flag2 = 'ALLOW_TO_FAILOVER'
backend_application_name2 = '172.16.7.212'

# フェイルオーバー設定
failover_command = '/home/postgres/pgpool-II/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'
follow_primary_command = '/home/postgres/pgpool-II/follow_primary.sh %d %h %p %D %m %H %M %P %r %R'

※補足
 backend_application_nameとは:
 接続元アプリの名前。
 replication_statカラムとreplication_sync_stateカラムを表示するために必要です。
 これが設定されていない場合、Pgpoolユーザは「どのレプリカの行なのか」を特定出来ません。
 primary_conninfoの名前と一致させる必要があります。

 failover_commandとは:
 フェイルオーバーを実行するために Pgpool-II から呼び出される外部コマンドです。
 主に「旧プライマリノードの切り分け」と 「新プライマリノードの昇格(promote)」を行います。

 follow_primary_commandとは:
 フェイルオーバーにより新プライマリノードが決定した後、
 残りのスタンバイノードを新プライマリノードに従わせるためにPgpool-II から呼び出される外部コマンドです。


/home/postgres/pgpool-II/sample_scripts配下にある、サンプルの実行ファイル
(=failover.sh.sample、follow_primary.sh.sample)をコピーして、
/home/postgres/pgpool-II配下に新たなファイルとして作成します。

$ cp -p /home/postgres/pgpool-II/sample_scripts/failover.sh.sample /home/postgres/pgpool-II/failover.sh
$ cp -p /home/postgres/pgpool-II/sample_scripts/follow_primary.sh.sample /home/postgres/pgpool-II/follow_primary.sh

failover.shとfollow_primary.shを開き、PGHOMEのディレクトリパスが正しいかを確認します。

$ vi /home/postgres/pgpool-II/failover.sh
$ vi /home/postgres/pgpool-II/follow_primary.sh

   ・
   ・
$PGHOME=/usr/pgsql-16

follow_primary.shを開き、各種パラメータが正しく設定されている事を確認します。

REPLUSER=repl_user
PCP_USER=pgpool
PGPOOL_PATH=/usr/bin
PCP_PORT=9898
POSTGRESQL_STARTUP_USER=postgres
SSH_KEY_FILE=id_rsa_pgpool

4.4. クライアント認証設定

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

Pgpool-II とPostgreSQL間で設定した認証方式(=scram-sha-256)を用いて、
クライアントとPgpool-II の間でも接続するために、
pgpool.confを以下のように編集し、Pgpool-II の認証ファイルであるpool_hba.confによる認証を許可します。

enable_pool_hba=on

pool_hba.confを以下のように編集し、クライアントが接続に用いる仮想IP並びに全ノードから、
Pgpool-II サーバーへの接続を許可します。

host    all     pgpool          172.16.7.201/32         scram-sha-256
host    all     postgres        172.16.7.201/32         scram-sha-256
host    all     pgpool          172.16.7.211/32         scram-sha-256
host    all     postgres        172.16.7.211/32         scram-sha-256
host    all     pgpool          172.16.7.212/32         scram-sha-256
host    all     postgres        172.16.7.212/32         scram-sha-256
host    all     pgpool          172.16.7.203/32         scram-sha-256
host    all     postgres        172.16.7.203/32         scram-sha-256

復号鍵ファイルである.pgpool_keyをpostgresユーザーのホームディレクトリ配下に作成し、
適切な権限を設定します。

$ echo client_login > ~/.pgpoolkey

$ chmod 600 ~/.pgpoolkey

作成した復号鍵を、他のサーバーにコピーします。

$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpoolkey postgres@172.16.7.211:
$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpoolkey postgres@172.16.7.212:

以下のコマンドを実行し、ユーザー名と、暗号化したパスワードのエントリをpool_passwdに登録します。
pgpool、postgres双方のユーザーにおいて暗号化を行います。

$ pg_enc -m -k /var/lib/pgsql/.pgpoolkey -u pgpool -p
$ pg_enc -m -k /var/lib/pgsql/.pgpoolkey -u postgres -p

db password:
trying to read key from file /var/lib/pgsql/.pgpoolkey

/etc/pgpool-II/pool_passwd配下にAESで暗号化されたパスワードが登録されるので、
これらを今回使用しているPgpool-II の設定ファイルのディレクトリ(home/postgres/pgpool-II/pool_passwd)
にコピーします。

$ cp -r /etc/pgpool-II/pool_passwd /home/postgres/pgpool-II/pool_passwd

pool_passwdにユーザー名と暗号化されたパスワードが問題なくエントリされているかを確認します。

$ cat /etc/pgpool-II/pool_passwd

4.5. Watchdog設定

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

pgpool.conf内のパラメータを編集し、Watchdogを有効にします。

# pgpool.conf

# Watchdogの有効化
use_watchdog = on

# 仮想IPの指定
delegate_ip = '172.16.7.203'

以下のファイルを確認し、postgresユーザーがパスワードなしにsudoコマンドを実行して
if_up/down_cmdやarping_cmdを実行する事が出来るか確認します。

$ sudo cat /etc/sudoers.d/pgpool

postgres ALL=NOPASSWD: /usr/sbin/ip
postgres ALL=NOPASSWD: /usr/sbin/arping

sudoを通して、仮想IPの起動、停止、状態の周知を実行するように、pgpool.confを以下のように設定します。

if_up_cmd = '/usr/bin/sudo /usr/sbin/ip addr add $_IP_$/32 dev ens3'
if_down_cmd = '/usr/bin/sudo /usr/sbin/ip addr del $_IP_$/32 dev ens3'
arping_cmd = '/usr/bin/sudo /usr/sbin/arping -U -w 3 -c 3 -I ens3 $_IP_$'

pgpool.conf内のパラメータを編集し、各種設定を行います。

# pgpool.conf

# ホスト別の設定
hostname0 = '172.16.7.201
wd_port0 = 9000
pgpool_port0 = 9999

hostname1 = '172.16.7.211'
wd_port1 = 9000
pgpool_port1 = 9999

hostname2 = '172.16.7.212'
wd_port2 = 9000
pgpool_port2 = 9999

# 死活監視設定
wd_lifecheck_method = 'heartbeat'
wd_interval = 10

# heartbeat設定
heartbeat_hostname0 = '172.16.7.201'
heartbeat_port0 = 9694
heartbeat_device0 = ''
heartbeat_hostname1 = '172.16.7.211
heartbeat_port1 = 9694
heartbeat_device1 = ''
heartbeat_hostname2 = '172.16.7.212'
heartbeat_port2 = 9694
heartbeat_device2 = ''

wd_lifecheck_method = 'heartbeat'の場合において、特定のノードを障害と判定するまでの秒数を指定するwd_heartbeat_deadtimeとハートビート信号を送る間隔の秒数を指定するwd_heartbeat_keepaliveを
以下のように設定します。

wd_heartbeat_keepalive = 2
wd_heartbeat_deadtime = 30

/etc/pgpool-II/sample_scripts/escalation.shを/home/postgres/pgpool-II/にコピーし、
wd_escalation_commandに新しいリーダー以外のPgpool-II ノードで仮想IPを停止するスクリプトを設定します。

$ cp -p /etc/pgpool-II/sample_scripts/escalation.sh.sample /home/postgres/pgpool-II/escalation.sh

wd_escalation_command = '/home/postgres/pgpool-II/escalation.sh'

escalation.shの中身を編集し、サーバーのホスト名、仮想IP、仮想IPを設定するネットワークインターフェース名を
正しく設定します。

  ・
  ・
PGPOOLS=(172.16.7.201 172.16.7.211 172.16.7.212)
VIP=172.16.7.203
DEVICE=ens3
CIDR_NETMASK=32

4.6. ログの設定

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

pgpool.confを編集し、ログ出力に関して設定を行います。

log_destination = 'stderr'
logging_collector = on
log_directory = '/home/postgres/pgpool-II/log'
log_filename = 'pgpool-%a.log'
log_truncate_on_rotation = on
log_rotation_age = 1d

4.7. 別サーバーへの各種設定ファイルの転送

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

Server1のPgpool-II 関連のconfファイル、.shファイル、pool_passwdファイルを172.16.7.211, 172.16.7.212に転送します。

$ scp -p /home/postgres/pgpool-II/{*.conf,*.sh,pool_passwd} postgres@172.16.7.211:/home/postgres/pgpool-II/
$ scp -p /home/postgres/pgpool-II/{*.conf,*.sh,pool_passwd} postgres@172.16.7.212:/home/postgres/pgpool-II/

pcp.conf                                    100%  898   680.0KB/s   00:00
pgpool.conf                                 100%   53KB  20.9MB/s   00:00
pool_hba.conf                               100% 3604     2.3MB/s   00:00
escalation.sh                               100% 1055   885.5KB/s   00:00
failover.sh                                 100% 2793   310.4KB/s   00:00
follow_primary.sh                           100% 4644   945.5KB/s   00:00
pool_passwd                                 100%   72    64.9KB/s   00:00

Server2, Server3にsshでログインし、転送した各種confファイル、.shファイル並びにpool_passwdファイルの
所有者と所属グループをpostgresに変更します。

$ ssh server2 "chown postgres:postgres /etc/pgpool-II/{*.conf,*.sh,pool_passwd}"
$ ssh server3 "chown postgres:postgres /etc/pgpool-II/{*.conf,*.sh,pool_passwd}"

5. 動作確認

5.1. 各ノードの状態確認

対象サーバー:172.16.7.201、172.16.7.211、172.16.7.212

各ノードで、PostgreSQLサーバーを起動します。

$ pg_ctl start -D /home/postgres/pgdata/pg16_3

各ノードで、pgpoolコマンドを用いてPgpool-II を起動します。

$ pgpool -f /home/postgres/pgpool-II/pgpool.conf -F /home/postgres/pgpool-II/pcp.conf -a /home/postgres/pgpool-II/pool_hba.conf

各ノードで、Pgpool-II の各種プロセスがバックエンドプロセスとして適切に実行されているか確認します。

$ ps -ef | grep pgpool


postgres  837351       1  0 14:59 ?        00:00:00 pgpool -f /home/postgres/pgpool-II/pgpool.conf -F /home/postgres/pgpool-II/pcp.conf -a /home/postgres/pgpool-II/pool_hba.conf
postgres  837352  837351  0 14:59 ?        00:00:00 pgpool: PgpoolLogger
postgres  837354  837351  0 14:59 ?        00:00:00 pgpool: watchdog
postgres  837367  837351  0 15:00 ?        00:00:00 pgpool: lifecheck
postgres  837368  837367  0 15:00 ?        00:00:00 pgpool: heartbeat receiver
    ・
    ・
    ・
postgres  837405  837351  0 15:00 ?        00:00:00 pgpool: PCP: wait for connection request
postgres  837406  837351  0 15:00 ?        00:00:00 pgpool: worker process
postgres  837407  837351  0 15:00 ?        00:00:00 pgpool: health check process(0)
postgres  837408  837351  0 15:00 ?        00:00:00 pgpool: health check process(1)
postgres  837409  837351  0 15:00 ?        00:00:00 pgpool: health check process(2)
postgres  837559  836897  0 15:01 pts/1    00:00:00 grep --color=auto pgpool

Server1上で、各ノードの状態を確認します。
node_id、hostname~last_status_changeまでのパラメータが表示されていれば問題ありません。

$ psql -h 172.16.7.203 -p 9999 -U pgpool -d postgres -c "show pool_nodes"


-[ RECORD 1 ]----------+--------------------
node_id                | 0
hostname               | 172.16.7.201
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | primary
pg_role                | primary
select_cnt             | 0
load_balance_node      | false
replication_delay      | 0
replication_state      |
replication_sync_state |
last_status_change     | 2026-02-05 14:59:58
-[ RECORD 2 ]----------+--------------------
node_id                | 1
hostname               | 172.16.7.211
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | standby
pg_role                | standby
select_cnt             | 0
load_balance_node      | false
replication_delay      | 0
replication_state      | streaming
replication_sync_state | async
last_status_change     | 2026-02-05 14:59:58
-[ RECORD 3 ]----------+--------------------
node_id                | 2
hostname               | 172.16.7.212
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | standby
pg_role                | standby
select_cnt             | 0
load_balance_node      | true
replication_delay      | 0
replication_state      | streaming
replication_sync_state | async
last_status_change     | 2026-02-05 14:59:58

pcp_watchdog_infoでPgpool-II のWatchdogの情報を確認します。
Node Name~Status Name、Membership Statusまでのパラメータが表示されていれば問題ありません。

$ pcp_watchdog_info -h 172.16.7.211 -p 9898 -U pgpool --verbose


Watchdog Cluster Information
Total Nodes              : 3
Remote Nodes             : 2
Member Remote Nodes      : 2
Alive Remote Nodes       : 2
Nodes required for quorum: 2
Quorum state             : QUORUM EXIST
Local node escalation    : YES
Leader Node Name         : 172.16.7.201:9999 Linux ebinaburano-ebina-rhel8
Leader Host Name         : 172.16.7.201

Watchdog Node Information
Node Name         : 172.16.7.201:9999 Linux ebinaburano-ebina-rhel8
Host Name         : 172.16.7.201
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 4
Status Name       : LEADER
Membership Status : MEMBER

Node Name         : 172.16.7.211:9999 Linux ebina2
Host Name         : 172.16.7.211
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 7
Status Name       : STANDBY
Membership Status : MEMBER

Node Name         : 172.16.7.212:9999 Linux ebina3
Host Name         : 172.16.7.212
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 7
Status Name       : STANDBY
Membership Status : MEMBER

5.2. Pgpool-II サーバー、仮想IPのフェイルオーバーの確認

リーダーノードであるServer1のPgpool-II を停止し、スタンバイノードで以下のコマンドを実行します。
スタンバイノードであるServer2またはServer3のどちらかがリーダーになることを確認します。

$ pgpool -f /home/postgres/pgpool-II/pgpool.conf -F /home/postgres/pgpool-II/pcp.conf -a /home/postgres/pgpool-II/pool_hba.conf -m f stop

2026-02-05 16:05:32.165: main pid 844982: LOG:  stop request sent to pgpool (pid: 837351). waiting for termination...
.done.


$  pcp_watchdog_info -h localhost -p 9898 -U pgpool --verbose

Watchdog Cluster Information
Total Nodes              : 3
Remote Nodes             : 2
Member Remote Nodes      : 2
Alive Remote Nodes       : 1
Nodes required for quorum: 2
Quorum state             : QUORUM EXIST
Local node escalation    : YES
Leader Node Name         : 172.16.7.211:9999 Linux ebina2
Leader Host Name         : 172.16.7.211

Watchdog Node Information
Node Name         : 172.16.7.211:9999 Linux ebina2
Host Name         : 172.16.7.211
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 4
Status Name       : LEADER
Membership Status : MEMBER

Node Name         : 172.16.7.201:9999 Linux ebinaburano-ebina-rhel8
Host Name         : 172.16.7.201
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 10
Status Name       : SHUTDOWN
Membership Status : MEMBER

Node Name         : 172.16.7.212:9999 Linux ebina3
Host Name         : 172.16.7.212
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 7
Status Name       : STANDBY
Membership Status : MEMBER

停止したServer1のPgpool-II を再起動し、スタンバイとして起動していることを確認します。

$ pgpool -f /home/postgres/pgpool-II/pgpool.conf -F /home/postgres/pgpool-II/pcp.conf -a /home/postgres/pgpool-II/pool_hba.conf


$ pcp_watchdog_info -h 172.16.7.211 -p 9898 -U pgpool --verbose


Watchdog Cluster Information
Total Nodes              : 3
Remote Nodes             : 2
Member Remote Nodes      : 2
Alive Remote Nodes       : 2
Nodes required for quorum: 2
Quorum state             : QUORUM EXIST
Local node escalation    : NO
Leader Node Name         : 172.16.7.211:9999 Linux ebina2
Leader Host Name         : 172.16.7.211

Watchdog Node Information
Node Name         : 172.16.7.201:9999 Linux ebinaburano-ebina-rhel8
Host Name         : 172.16.7.201
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 7
Status Name       : STANDBY
Membership Status : MEMBER

Node Name         : 172.16.7.211:9999 Linux ebina2
Host Name         : 172.16.7.211
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 4
Status Name       : LEADER
Membership Status : MEMBER

Node Name         : 172.16.7.212:9999 Linux ebina3
Host Name         : 172.16.7.212
Delegate IP       : 172.16.7.203
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 7
Status Name       : STANDBY
Membership Status : MEMBER

リーダーノードであるServer2上でip aコマンドを実行し、Linux上で正しくVIPが移り変わっているか確認します。

$ ip a



ens3:

inet 172.16.7.203/32 scope global ens3

5.3. PostgreSQLサーバー(バックエンド)のフェイルオーバーの確認

Server1上で、現在のノード状況を確認します。

$ psql -h 172.16.7.203 -p 9999 -U pgpool -d postgres -c "show pool_nodes"

-[ RECORD 1 ]----------+--------------------
node_id                | 0
hostname               | 172.16.7.201
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | primary
pg_role                | primary
select_cnt             | 0
load_balance_node      | false
replication_delay      | 0
replication_state      |
replication_sync_state |
last_status_change     | 2026-02-05 16:51:56
-[ RECORD 2 ]----------+--------------------
node_id                | 1
hostname               | 172.16.7.211
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | standby
pg_role                | standby
select_cnt             | 0
load_balance_node      | false
replication_delay      | 0
replication_state      | streaming
replication_sync_state | async
last_status_change     | 2026-02-05 16:51:56
-[ RECORD 3 ]----------+--------------------
node_id                | 2
hostname               | 172.16.7.212
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | standby
pg_role                | standby
select_cnt             | 0
load_balance_node      | true
replication_delay      | 0
replication_state      | streaming
replication_sync_state | async
last_status_change     | 2026-02-05 16:51:56

プライマリであるServer1のPostgreSQLサーバーを停止します。

$ pg_ctl -m f stop

フェイルオーバーが発生し、Server2が プライマリに昇格したことを確認します。

$ psql -h 172.16.7.203 -p 9999 -U pgpool -d postgres -c "show pool_nodes"


-[ RECORD 1 ]----------+--------------------
node_id                | 0
hostname               | 172.16.7.201
port                   | 5432
status                 | down
pg_status              | down
lb_weight              | 0.333333
role                   | standby
pg_role                | unknown
select_cnt             | 0
load_balance_node      | false
replication_delay      | 0
replication_state      |
replication_sync_state |
last_status_change     | 2026-02-16 16:01:37
-[ RECORD 2 ]----------+--------------------
node_id                | 1
hostname               | 172.16.7.211
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | primary
pg_role                | primary
select_cnt             | 0
load_balance_node      | false
replication_delay      | 0
replication_state      |
replication_sync_state |
last_status_change     | 2026-02-16 16:01:37
-[ RECORD 3 ]----------+--------------------
node_id                | 2
hostname               | 172.16.7.212
port                   | 5432
status                 | up
pg_status              | up
lb_weight              | 0.333333
role                   | standby
pg_role                | standby
select_cnt             | 0
load_balance_node      | true
replication_delay      | 0
replication_state      | streaming
replication_sync_state | async
last_status_change     | 2026-02-16 16:02:44

スタンバイであるServer3のPostgreSQLサーバー上で、walを受信しているか確認します。

$ repl_db=# select * from pg_stat_wal_receiver;


-[ RECORD 1 ]---------+-----------------------------------------------------------------------------------------------------------
pid                   | 5810
status                | streaming
receive_start_lsn     | 2/E000000
receive_start_tli     | 19
written_lsn           | 2/E000268
flushed_lsn           | 2/E000268
received_tli          | 19
last_msg_send_time    | 2026-02-16 02:06:12.779868-05
last_msg_receipt_time | 2026-02-16 02:06:12.017861-05
latest_end_lsn        | 2/E000268
latest_end_time       | 2026-02-16 02:01:42.567689-05
slot_name             | 172_16_7_212
sender_host           | 172.16.7.211
sender_port           | 5432
conninfo              | host=172.16.7.211 port=5432 user=repl_user application_name=172.16.7.212 passfile='/var/lib/pgsql/.pgpass'

Advancedサポートサービスのご紹介

PostgreSQL保守Advancedサポートサービスでは、PostgreSQL技術者による24時間365日体制のサポートのもと、PostgreSQLの技術的な問い合わせや、障害調査、pg_statsinfoを含む指定のOSSツールのサポートに対応します。
詳細はこちらをご覧ください。