pgpool-Ⅱを構築~PostgreSQLをロードバランス&フェイルオーバー可能とする~
システムに欠かせないミドルウェアの世界

中山テック 代表の中山です。

さて、現在代表のPCに入っているVMWareには4台の仮想マシンがセットされています(!?)。

それも今回の最大目的である「PostgreSQL × pgpoolⅡ」でロードバランス&フェイルオーバーを導入したいためです。

では早速導入していきましょう!

PostgreSQLのインストールはこちら







  • VMware × CentOS関連索引

※【追記】上記の図はServer3、4もVIPの中におります・・・大変失礼しました

PostgreSQLを2台構成にし、常にデータ同期を取りつつ片系が落ちても運用可能な状態にします。

そのためにpgpool-Ⅱが必須です。

また、それぞれを監視することで「誰が落ちているか」を瞬時に判断し、フェイルオーバーを実施してくれます。

・pgpool⇒PostgreSQL全体の監視

・Watchdog⇒pgpool全体の監視

・ハートビート⇒Watchdogやpgpoolから出される死活監視(UDP通信)。一定間隔で通信が行われる。仮に主系からの通信が途絶えたら副系が主系に切り替わる

pgpoolインストール

必要パッケージ

まずはPostgreSQLとpgpool-Ⅱ、LLVM関連パッケージを追加しましょう(PostgreSQLの追加手順と同様)。

sudo yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
sudo yum install https://www.pgpool.net/yum/rpms/4.2/redhat/rhel-8-x86_64/pgpool-II-release-4.2-1.noarch.rpm
sudo yum -y install epel-release centos-release-scl

続いてインストールしてきたいのですが、対象パッケージは下記です(yum search postgresqlで検索)。

・postgresql15.x86_64

・pgpool-II-pg15-extensions ※PostgreSQLが入っているサーバにも必須

・pgpool-II-pg15

・pgpool-II-pg15-debuginfo

・pgpool-II-pg15-devel

あれっ?postgresql15入れるの?とお思いかもしれませんが、あくまでもクライアントです。

psqlコマンドは使うのでクライアントだけインストールします。

パッケージ詳細はpgpoo-Ⅱ文書のページをご覧ください。

インストール

片っ端からインストールしていきます。

yum -y install postgresql15.x86_64
yum -y install pgpool-II-pg15-extensions
yum -y install pgpool-II-pg15
yum -y install pgpool-II-pg15-debuginfo
yum -y install pgpool-II-pg15-devel

途中で「※公開鍵がインストールされていません」と出ますがしっかりインストールされていました。

PostgreSQL側の設定

オンラインリカバリ機能の導入

PostgreSQL側(Server3、4)もリカバリ対象になるので下記をインストールします。

yum -y install pgpool-II-pg15-extensions

アーカイブディレクトリの作成

DBクラッシュ時に備えたチェックポイントを格納するディレクトリです。

※ここの時点から復旧するよ!と言ったログです

作成後は「postgres」のユーザ:グループに修正しましょう。

※Server3、4いずれも設定

mkdir -p /var/lib/pgsql/15/archivedir
chown -R postgres:postgres /var/lib/pgsql/15/archivedir

confファイル修正

pgpool側からの死活監視で通信されるので、PostgreSQLのコンフィグファイルを修正しましょう。

cd /var/lib/pgsql/15/data/ ※バージョンや環境により異なります
vi postgresql.conf

修正箇所は下記の通り(Server3、4いずれも)。

listen_addresses = '*'

wal_level = replica ※hot_stanbyと書かれてるサイトもありますが、現在はreplicaで設定

max_wal_senders = 2

archive_mode = on

archive_command = 'cp "%p" "/var/lib/pgsql/15/archivedir/%f"'

※追記:「archive_command」に15を入れ忘れたせいでアーカイブ出来ておりませんでした(汗

クライアント認証ファイル修正

postgresql.confファイルと同階層にある「pg_hba.conf」ファイルを修正します。

※PrimaryであるServer3のみ

cd /var/lib/pgsql/15/data/
vi pg_hba.conf

~~~~ 下記を追加 ~~~~

host    all             all             0.0.0.0/24              scram-sha-256
host    replication     all             0.0.0.0/24              scram-sha-256

◆リカバリ用コマンド
psql template1 -c "CREATE EXTENSION pgpool_recovery"

ユーザ追加

Server3でreplとpgpoolユーザを追加します。

sudo su - postgres
psql

ALTER ROLE postgres WITH PASSWORD 'postgres';
CREATE ROLE pgpool WITH PASSWORD 'pgpool' LOGIN SUPERUSER;
CREATE ROLE repl WITH PASSWORD 'repl' LOGIN REPLICATION;
GRANT pg_monitor TO pgpool;
select * from pg_uesr;

 usename  | usesysid | usecreatedb | usesuper | userepl | usebypassrls |  passwd  | valuntil | useconfig
----------+----------+-------------+----------+---------+--------------+----------+----------+-----------
 postgres |       10 | t           | t        | t       | t            | ******** |          |
 pgpool   |    16388 | f           | t        | f       | f            | ******** |          |
 repl     |    16389 | f           | f        | t       | f            | ******** |          |
(3 行)

パスワード入力なしでsshアクセス設定

自動フェイルオーバー、オンラインリカバリを導入するなら必須です。

server3、4のpostgresユーザでやっておきましょう。

useradd postgres ←いるなら不要
passwd postgres ←設定済みなら不要
sudo su - postgres
mkdir .ssh
chmod 700 ~/.ssh
cd ~/.ssh
ssh-keygen -t rsa -f id_rsa_pgpool ←パスワードが求められるが入力なしでEnter
ssh-copy-id -i id_rsa_pgpool.pub postgres@server1
ssh-copy-id -i id_rsa_pgpool.pub postgres@server2
ssh-copy-id -i id_rsa_pgpool.pub postgres@server3←自分自身はなくてもいい
ssh-copy-id -i id_rsa_pgpool.pub postgres@server4

上手く行けば


Number of key(s) added: 1

と出る

また、root向けは
ssh-copy-id -i id_rsa_pgpool.pub root@server1
ssh-copy-id -i id_rsa_pgpool.pub root@server2
ssh-copy-id -i id_rsa_pgpool.pub root@server3
ssh-copy-id -i id_rsa_pgpool.pub root@server4

パスワード入力なしでsshアクセス確認

設定したはいいけど出来ませんでした、とならないように確認します。

ssh postgres@server1 -i ~/.ssh/id_rsa_pgpool
ssh postgres@server2 -i ~/.ssh/id_rsa_pgpool
ssh postgres@server3 -i ~/.ssh/id_rsa_pgpool ←自分自身設定していない場合は不要
ssh postgres@server4 -i ~/.ssh/id_rsa_pgpool

もしパスワードを求められたら「/var/log/secure」で確認します。

私の場合はpostgresユーザでの自動sshログインがダメだったので、SELinuxを無効にすることで行けました

◆暫定処置
setenforce 0

◆恒久対応
vi /etc/selinux/config
SELINUX=disabled
サーバserver1(r)server1(p)server2(r)server2(p)server3(r)server3(p)server4(r)server4(p)
server1〇〇〇〇〇〇〇〇
server2〇〇〇〇〇〇〇〇
server3〇〇〇〇〇〇〇〇
server4〇〇〇〇〇〇〇〇
※〇が2つ並んでいる箇所は「root」と「postgres」からの公開鍵連携作業が必要

pgpass

なくてもいいんですが、毎回パスワード聞かれるのも面倒なので設定します。

※postgresユーザのホーム

vi .pgpass

server3のIPアドレス:5432:replication:repl:repl
server4のIPアドレス:5432:replication:repl:repl
server3のIPアドレス:5432:postgres:postgres:postgres
server4のIPアドレス:5432:postgres:postgres:postgres

exit

chmod 600 .pgpass


  • システム開発関連記事

pgpool側設定

これでPostgreSQL側の準備が整ったので、pgpool側の設定をしていきます。

confファイルの修正

今回はPostgreSQLと切り離しているので色々と設定します。

まずはpcp.confですが、これはpgpoolのステータス管理、リモートからの停止を行うための重要なパスワードです。

cp /etc/pgpool/pcp.conf.sample /etc/pgpool/pcp.
conf ⇒サンプルからコピー

echo 'postgres:'`pg_md5 postgres` >> /etc/pgpool-II/pcp.conf ⇒postgresのパスワードでアクセス可能とします。pg_md5でハッシュ値を登録

続いては重要なpgpool.confの設定です。

またしてもサンプルからコピーして編集します(root権限)。

cp pgpool.conf.sample pgpool.conf
vi pgpool.conf

backend_clustering_mode = 'streaming_replication'

listen_addresses = '*'

pcp_listen_address = '*'
pcp_port = '9898'
pcp_socket_dir = '/var/run/postgresql' # インストール時はデフォルトで/tmp配下に作られるので変更

unix_socket_directories = '/var/run/postgresql' # インストール時はデフォルトで/tmp配下に作られるので変更

wd_ipc_socket_dir = '/var/run/postgresql' # インストール時はデフォルトで/tmp配下に作られるので変更

sr_check_user = 'postgres'
sr_check_passwd = ''

enable_consensus_with_half_votes = on # 本来は奇数構成にして投票し、誰がLEADERになるか決めるが2台構成時はこちらを指定

health_check_period = 5
health_check_timeout = 30
health_check_user = 'postgres'
health_check_password = ''
health_check_max_retries = 3

backend_hostname0 = 'server3のIPアドレス'
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/var/lib/pgsql/15/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_application_name0 = 'server3'

backend_hostname1 = 'server4のIPアドレス'
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/var/lib/pgsql/15/data'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_application_name1 = 'server4'

failover_command = '/etc/pgpool/failover.sh %d  %h %p %D %m %H %M %P %r %R %N %S'
#follow_primary_command = '/etc/pgpool-II/follow_primary.sh %d  %h %p %D %m %H %M %P %r %R

recovery_uesr = 'postgres'
recovery_password = ''
recovery_1st_stage_command = 'recovery_1st_stage'

enable_pool_hba = on ←後述するhbaファイルを使用するかどうか

use_watchdog = on ←冒頭で触れたwatchdogを使用するかどうか
delegate_ip = '未使用のIPを指定(なんでもいい)' # pool内の仮想IP(VIP)を指定

if_cmd_path = '/sbin'
if_up_cmd = '/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev [IF名(ens~)] label [IF名(ens~)]:0'
if_down_cmd = '/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev [IF名(ens~)]'
arping_path = '/usr/sbin'
arping_cmd = '/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I [IF名(ens~)]'

hostname0 = 'server1のIPアドレス'
wd_port0 = 9000
pgpool_port0 = 9999
hostname1 = 'server2のIPアドレス'
wd_port1 = 9000
pgpool_port1 = 9999

wd_lifecheck_method = 'heartbeat'
wd_interval = 10
hostname0 = 'server1のIPアドレス'
wd_port0 = 9000
pgpool_port0 = 9999
hostname1 = 'server2のIPアドレス'
wd_port1 = 9000
pgpool_port1 = 9999

heartbeat_hostname0 = 'server1のIPアドレス'
heartbeat_port0 = 9694
heartbeat_device0 = 'ens33'
heartbeat_hostname1 = 'server2のIPアドレス'
heartbeat_port1 = 9694
heartbeat_device1 = 'ens33'

heartbeat_destination1 = 'server2のIPアドレス' # server2のconfファイル設定時はserver1のIPアドレス
heartbeat_destination_port1 = 9694

wd_heartbeat_keepalive = 2
wd_heartbeat_deadtime = 30
wd_escalation_command = '/etc/pgpool/escalation.sh'

other_pgpool_hostname1 = 'server2のIPアドレス' # server2のconfファイル設定時はserver1のIPアドレス
other_pgpool_port1 = 9999
other_wd_port1 = 9000

log_destination = 'stderr'
logging_collector = on
log_directory = '/var/log/pgpool'
log_filename = 'pgpool-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = on
log_rotation_age = 1d
log_rotation_size = 20MB

pgpoolの「0」や「1」は「/etc/pgpool」配下の「pgpool_node_id」の番号に依存します。

なので作ってあげましょう!

touch /etc/pgpool/pgpool_node_id
vi /etc/pgpool/pgpool_node_id

◆1台目のpgpool_node_idは、1行目に下記を記載
0

◆2台目のpgpool_node_idは、1行目に下記を記載
1

下記のファイルの権限を変える必要があります。

chown postgres:postgres {pgpool.conf,pool_hba.conf,pool_passwd}

フェイエルオーバー用ファイルの修正

片側が落ちた時に副系をPRIMARYにするためには2つのシェルファイルが必要です。

cp failover.sh.sample failover.sh
cp escalation.sh.sample escalation.sh
chown postgres:postgres /etc/pgpool/{escalation.sh,failover.sh}

escalation.shの修正箇所は下記の通り。

PGPOOLS=(server1 server2) ←pgpoolをインストールしたIPアドレス
VIP=pgpool.confで設定したdelegate_ip
DEVICE=IF名(ens~)

◆SSHのポート番号を変えた場合は下記を追加

SSH_OPTIONS="-p ポート番号 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}"

failover.shの修正箇所は下記の通り(bin/pg_ctlがある場所を指定してください)。

PGHOME=/usr/pgsql-15

◆SSHのポート番号を変えた場合は下記を追加

SSH_OPTIONS="-p ポート番号 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}"

SSHで自動ログイン設定したのはこの処理がしたいためです。

リカバリファイル、リモートスタートファイルをPostgreSQLサーバへ移動

コンフィグファイルが入っている場所の「recovery_1st_stage」「pgpool_remote_start」を修正します。

cp pgpool_remote_start.sample pgpool_remote_start
chmod 755 pgpool_remote_start
cp recovery_1st_stage.sample recovery_1st_stage
chmod 755 recovery_1st_stage
chown postgres:postgres /etc/pgpool/{pgpool_remote_start,recovery_1st_stage}

~~~~~ 修正内容 ~~~~~
PGHOME=/usr/pgsql-15

◆SSHのポート番号を変えた場合は下記を追加

SSH_OPTIONS="-p ポート番号 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}"

PostgreSQL側に移動、置く場所はdata配下です。

※例のごとくポート番号が違う場合は「-P」で指定(scpコマンドは大文字P)

scp -P ポート番号 pgpool_remote_start postgres@192.168.230.128:/var/lib/pgsql/15/data/
scp -P ポート番号 recovery_1st_stage postgres@192.168.230.128:/var/lib/pgsql/15/data/

pgpool⇒PostgreSQL側へのアクセス定義

confファイルが入っているディレクトリ「pool_hba.conf」を修正します。

cp pool_hba.conf.sample pool_hba.conf

host    all         postgres    0.0.0.0/0             scram-sha-256

※上記は誰でもアクセス可能な状態なので、うまい具合に調整しましょう

pool_passwd

pgpool.conf内で「enable_pool_hba = on」としてる場合に下記の作業が必要です。

※md5認証が必要となるため

touch /etc/pgpool/pool_passwd
chown postgres:postgres /etc/pgpool/pool_passwd
sudo su - postgres
echo 'pgpoolkey' > ~/.pgpoolkey
chmod 600 ~/.pgpoolkey
pg_enc -m -k ~/.pgpoolkey -u postgres -p
cat /etc/pgpool/pool_passwd

パスワードはこちらに合わせてください

プロセスファイル格納場所作成

最後にプロセスファイル「pgpool.pid」を格納するディレクトリを作成します。

mkdir -p /var/run/pgpool
chown -R postgres:postgres /var/run/pgpool

ポート開放

・pgpool⇒9999ポート

・PCP受付⇒9898ポート

・watchdog⇒9000ポート

・heartbeat(死活監視)⇒9694ポート(UDP)

firewall-cmd --permanent --zone=public --add-service=postgresql
firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp --add-port=9000/tcp --add-port=9694/udp
firewall-cmd --reload

ポート開放

if_up/down_cmdやarping_cmdを実行するため、sudoに下記を定義します。

※root権限
visudo
postgres ALL=NOPASSWD: /sbin/ip
postgres ALL=NOPASSWD: /usr/sbin/arping

pgpoolプロセスファイル恒久対応

/var/run配下は再起動で消えるので下記のファイルを作成・記述します。

vi /etc/tmpfiles.d/pgpool.conf

#Type   Path                    Mode    UID      GID       Age  Argument
d       /var/run/pgpool         0755    postgres postgres  - 

◆手作業で実施する場合

mkdir -p /var/run/pgpool
chown -R postgres:postgres /var/run/pgpool

実行!

ip a

~中略~
    inet VIP/24 scope global secondary IF名:0
       valid_lft forever preferred_lft forever

と出てればOK!!

お疲れさまでした(汗 VIPもちゃんと出てますね。

書いてる方も疲れますねコレ。早速立ち上げてみましょう。

systemctl start pgpool-II.service

2024-02-20 19:50:12.518: main pid 8549: LOG:  memory cache initialized
2024-02-20 19:50:12.518: main pid 8549: DETAIL:  memcache blocks :64
2024-02-20 19:50:12.522: main pid 8549: LOG:  pool_discard_oid_maps: discarded memqcache oid maps
2024-02-20 19:50:12.529: main pid 8549: LOG:  waiting for watchdog to initialize
2024-02-20 19:50:12.530: watchdog pid 8559: LOG:  setting the local watchdog node name to "192.168.230.130:9999 Linux study_03"
2024-02-20 19:50:12.530: watchdog pid 8559: LOG:  watchdog cluster is configured with 1 remote nodes
2024-02-20 19:50:12.530: watchdog pid 8559: LOG:  watchdog remote node:0 on 192.168.230.131:9000
2024-02-20 19:50:12.530: watchdog pid 8559: LOG:  interface monitoring is disabled in watchdog
2024-02-20 19:50:12.530: watchdog pid 8559: LOG:  watchdog node state changed from [DEAD] to [LOADING]
2024-02-20 19:50:17.538: watchdog pid 8559: LOG:  watchdog node state changed from [LOADING] to [JOINING]
2024-02-20 19:50:21.544: watchdog pid 8559: LOG:  watchdog node state changed from [JOINING] to [INITIALIZING]
2024-02-20 19:50:22.546: watchdog pid 8559: LOG:  I am the only alive node in the watchdog cluster
2024-02-20 19:50:22.546: watchdog pid 8559: HINT:  skipping stand for coordinator state
2024-02-20 19:50:22.546: watchdog pid 8559: LOG:  watchdog node state changed from [INITIALIZING] to [LEADER]
2024-02-20 19:50:22.546: watchdog pid 8559: LOG:  Setting failover command timeout to 8
2024-02-20 19:50:22.546: watchdog pid 8559: LOG:  I am announcing my self as leader/coordinator watchdog node
2024-02-20 19:50:26.552: watchdog pid 8559: LOG:  I am the cluster leader node
2024-02-20 19:50:26.552: watchdog pid 8559: DETAIL:  our declare coordinator message is accepted by all nodes
2024-02-20 19:50:26.552: watchdog pid 8559: LOG:  setting the local node "192.168.230.130:9999 Linux study_03" as watchdog cluster leader
2024-02-20 19:50:26.552: watchdog pid 8559: LOG:  signal_user1_to_parent_with_reason(1)
2024-02-20 19:50:26.552: watchdog pid 8559: LOG:  I am the cluster leader node. Starting escalation process
2024-02-20 19:50:26.553: watchdog pid 8559: LOG:  escalation process started with PID:8582
2024-02-20 19:50:26.553: main pid 8549: LOG:  watchdog process is initialized
2024-02-20 19:50:26.553: main pid 8549: DETAIL:  watchdog messaging data version: 1.2
2024-02-20 19:50:26.554: main pid 8549: LOG:  Pgpool-II parent process received SIGUSR1
2024-02-20 19:50:26.554: main pid 8549: LOG:  Pgpool-II parent process received watchdog state change signal from watchdog
2024-02-20 19:50:26.555: main pid 8549: LOG:  unix_socket_directories[0]: /var/run/postgresql/.s.PGSQL.9999
2024-02-20 19:50:26.555: main pid 8549: LOG:  listen address[0]: *
2024-02-20 19:50:26.555: main pid 8549: LOG:  Setting up socket for 0.0.0.0:9999
2024-02-20 19:50:26.555: main pid 8549: LOG:  Setting up socket for :::9999
2024-02-20 19:50:26.566: main pid 8549: LOG:  find_primary_node_repeatedly: waiting for finding a primary node
2024-02-20 19:50:26.585: watchdog_utility pid 8582: LOG:  watchdog: escalation started
2024-02-20 19:50:26.593: life_check pid 8583: LOG:  2 watchdog nodes are configured for lifecheck
2024-02-20 19:50:26.593: life_check pid 8583: LOG:  watchdog nodes ID:0 Name:"192.168.230.130:9999 Linux study_03"
2024-02-20 19:50:26.593: life_check pid 8583: DETAIL:  Host:"192.168.230.130" WD Port:9000 pgpool-II port:9999
2024-02-20 19:50:26.593: life_check pid 8583: LOG:  watchdog nodes ID:1 Name:"Not_Set"
2024-02-20 19:50:26.593: life_check pid 8583: DETAIL:  Host:"192.168.230.131" WD Port:9000 pgpool-II port:9999
+ POSTGRESQL_STARTUP_USER=postgres
+ SSH_KEY_FILE=id_rsa_pgpool
+ SSH_OPTIONS='-p 50022 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_rsa_pgpool'
+ PGPOOLS=(192.168.230.130 192.168.230.131)
+ VIP=192.168.230.100
+ DEVICE=ens33
+ for pgpool in '"${PGPOOLS[@]}"'
+ '[' study_03 = 192.168.230.130 ']'
+ ssh -T -p 50022 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i '~/.ssh/id_rsa_pgpool' postgres@192.168.230.130 '
        /usr/bin/sudo /sbin/ip addr del 192.168.230.100/24 dev ens33
    '
Warning: Permanently added '[192.168.230.130]:50022' (ECDSA) to the list of known hosts.
2024-02-20 19:50:26.667: main pid 8549: LOG:  find_primary_node: primary node is 0
2024-02-20 19:50:26.667: main pid 8549: LOG:  find_primary_node: standby node is 1
2024-02-20 19:50:26.667: main pid 8549: LOG:  listen address[0]: localhost
2024-02-20 19:50:26.667: main pid 8549: LOG:  Setting up socket for ::1:9898
2024-02-20 19:50:26.667: main pid 8549: LOG:  Setting up socket for 127.0.0.1:9898
2024-02-20 19:50:26.671: health_check pid 8625: LOG:  process started
2024-02-20 19:50:26.672: sr_check_worker pid 8623: LOG:  process started
2024-02-20 19:50:26.673: health_check pid 8624: LOG:  process started
2024-02-20 19:50:26.674: pcp_main pid 8622: LOG:  PCP process: 8622 started
2024-02-20 19:50:26.686: main pid 8549: LOG:  pgpool-II successfully started. version 4.4.2 (nurikoboshi)
2024-02-20 19:50:26.686: main pid 8549: LOG:  node status[0]: 1
2024-02-20 19:50:26.686: main pid 8549: LOG:  node status[1]: 2
2024-02-20 19:50:27.602: heart_beat_sender pid 8618: LOG:  set SO_REUSEPORT option to the socket
2024-02-20 19:50:27.602: heart_beat_sender pid 8618: LOG:  creating socket for sending heartbeat
2024-02-20 19:50:27.602: heart_beat_sender pid 8618: DETAIL:  set SO_REUSEPORT
2024-02-20 19:50:27.602: heart_beat_receiver pid 8617: LOG:  set SO_REUSEPORT option to the socket
2024-02-20 19:50:27.603: heart_beat_receiver pid 8617: LOG:  creating watchdog heartbeat receive socket.
2024-02-20 19:50:27.603: heart_beat_receiver pid 8617: DETAIL:  set SO_REUSEPORT
RTNETLINK answers: Cannot assign requested address
+ for pgpool in '"${PGPOOLS[@]}"'
+ '[' study_03 = 192.168.230.131 ']'
+ ssh -T -p 50022 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i '~/.ssh/id_rsa_pgpool' postgres@192.168.230.131 '
        /usr/bin/sudo /sbin/ip addr del 192.168.230.100/24 dev ens33
    '
Warning: Permanently added '[192.168.230.131]:50022' (ECDSA) to the list of known hosts.
RTNETLINK answers: Cannot assign requested address
+ exit 0
2024-02-20 19:50:34.412: watchdog_utility pid 8582: LOG:  watchdog escalation successful
2024-02-20 19:50:38.616: watchdog_utility pid 8582: LOG:  successfully acquired the delegate IP:"192.168.230.100"
2024-02-20 19:50:38.616: watchdog_utility pid 8582: DETAIL:  'if_up_cmd' returned with success
2024-02-20 19:50:38.616: watchdog pid 8559: LOG:  watchdog escalation process with pid: 8582 exit with SUCCESS.


~副系立ち上げ後

2024-02-20 19:51:32.186: watchdog pid 8559: LOG:  new watchdog node connection is received from "192.168.230.131:57056"
2024-02-20 19:51:32.187: watchdog pid 8559: LOG:  new node joined the cluster hostname:"192.168.230.131" port:9000 pgpool_port:9999
2024-02-20 19:51:32.187: watchdog pid 8559: DETAIL:  Pgpool-II version:"4.4.2" watchdog messaging version: 1.2
2024-02-20 19:51:32.187: watchdog pid 8559: LOG:  new outbound connection to 192.168.230.131:9000
2024-02-20 19:51:38.200: watchdog pid 8559: LOG:  adding watchdog node "192.168.230.131:9999 Linux study_04" to the standby list
2024-02-20 19:51:38.200: watchdog pid 8559: LOG:  signal_user1_to_parent_with_reason(3)
2024-02-20 19:51:38.201: main pid 8549: LOG:  Pgpool-II parent process received SIGUSR1
2024-02-20 19:51:38.201: main pid 8549: LOG:  Pgpool-II parent process received watchdog quorum change signal from watchdog
2024-02-20 19:51:38.202: watchdog pid 8559: LOG:  Setting failover command timeout to 8
2024-02-20 19:51:38.202: main pid 8549: LOG:  watchdog cluster now holds the quorum
2024-02-20 19:51:38.202: main pid 8549: DETAIL:  updating the state of quarantine backend nodes
2024-02-20 19:52:06.594: life_check pid 8583: LOG:  watchdog: lifecheck started

うーん、watchdogがVIPに組み込まれてないですね・・・

 ⇒escalation.shのVIP対象アドレスをカンマで区切ってたので直しましたが、まだ駄目ですね

  ⇒治りました。confファイルのif_cmd_downの「addr」が抜けてました・・・・

2024-02-20 19:27:23.665: watchdog_utility pid 6797: LOG:  successfully acquired the delegate IP:"192.168.230.100"
2024-02-20 19:27:23.665: watchdog_utility pid 6797: DETAIL:  'if_up_cmd' returned with success
2024-02-20 19:27:23.667: watchdog pid 6783: LOG:  watchdog escalation process with pid: 6797 exit with SUCCESS.

副系はこんな感じ

2024-02-20 19:51:32.184: main pid 4308: LOG:  waiting for watchdog to initialize
2024-02-20 19:51:32.185: watchdog pid 4318: LOG:  setting the local watchdog node name to "192.168.230.131:9999 Linux study_04"
2024-02-20 19:51:32.185: watchdog pid 4318: LOG:  watchdog cluster is configured with 1 remote nodes
2024-02-20 19:51:32.185: watchdog pid 4318: LOG:  watchdog remote node:0 on 192.168.230.130:9000
2024-02-20 19:51:32.185: watchdog pid 4318: LOG:  interface monitoring is disabled in watchdog
2024-02-20 19:51:32.185: watchdog pid 4318: LOG:  watchdog node state changed from [DEAD] to [LOADING]
2024-02-20 19:51:32.186: watchdog pid 4318: LOG:  new outbound connection to 192.168.230.130:9000
2024-02-20 19:51:32.187: watchdog pid 4318: LOG:  new watchdog node connection is received from "192.168.230.130:15036"
2024-02-20 19:51:32.188: watchdog pid 4318: LOG:  new node joined the cluster hostname:"192.168.230.130" port:9000 pgpool_port:9999
2024-02-20 19:51:32.188: watchdog pid 4318: DETAIL:  Pgpool-II version:"4.4.2" watchdog messaging version: 1.2
2024-02-20 19:51:37.194: watchdog pid 4318: LOG:  watchdog node state changed from [LOADING] to [JOINING]
2024-02-20 19:51:37.196: watchdog pid 4318: LOG:  setting the remote node "192.168.230.130:9999 Linux study_03" as watchdog cluster leader
2024-02-20 19:51:37.196: watchdog pid 4318: LOG:  watchdog node state changed from [JOINING] to [INITIALIZING]
2024-02-20 19:51:38.198: watchdog pid 4318: LOG:  watchdog node state changed from [INITIALIZING] to [STANDBY]
2024-02-20 19:51:38.201: watchdog pid 4318: LOG:  signal_user1_to_parent_with_reason(1)
2024-02-20 19:51:38.201: watchdog pid 4318: LOG:  successfully joined the watchdog cluster as standby node
2024-02-20 19:51:38.201: watchdog pid 4318: DETAIL:  our join coordinator request is accepted by cluster leader node "192.168.230.130:9999 Linux study_03"
2024-02-20 19:51:38.201: watchdog pid 4318: LOG:  signal_user1_to_parent_with_reason(3)
2024-02-20 19:51:38.202: main pid 4308: LOG:  watchdog process is initialized
2024-02-20 19:51:38.202: main pid 4308: DETAIL:  watchdog messaging data version: 1.2
2024-02-20 19:51:38.202: main pid 4308: LOG:  Pgpool-II parent process received SIGUSR1
2024-02-20 19:51:38.202: main pid 4308: LOG:  Pgpool-II parent process received watchdog quorum change signal from watchdog
2024-02-20 19:51:38.203: main pid 4308: LOG:  watchdog cluster now holds the quorum
2024-02-20 19:51:38.203: main pid 4308: DETAIL:  updating the state of quarantine backend nodes
2024-02-20 19:51:38.203: main pid 4308: LOG:  Pgpool-II parent process received watchdog state change signal from watchdog
2024-02-20 19:51:38.203: main pid 4308: LOG:  we have joined the watchdog cluster as STANDBY node
2024-02-20 19:51:38.203: main pid 4308: DETAIL:  syncing the backend states from the LEADER watchdog node
2024-02-20 19:51:38.204: watchdog pid 4318: LOG:  received the get data request from local pgpool-II on IPC interface
2024-02-20 19:51:38.204: watchdog pid 4318: LOG:  get data request from local pgpool-II node received on IPC interface is forwarded to leader watchdog node "192.168.230.130:9999 Linux study_03"
2024-02-20 19:51:38.204: watchdog pid 4318: DETAIL:  waiting for the reply...
2024-02-20 19:51:38.205: main pid 4308: LOG:  leader watchdog node "192.168.230.130:9999 Linux study_03" returned status for 2 backend nodes
2024-02-20 19:51:38.205: main pid 4308: LOG:  unix_socket_directories[0]: /var/run/postgresql/.s.PGSQL.9999
2024-02-20 19:51:38.205: main pid 4308: LOG:  listen address[0]: *
2024-02-20 19:51:38.205: main pid 4308: LOG:  Setting up socket for 0.0.0.0:9999
2024-02-20 19:51:38.205: main pid 4308: LOG:  Setting up socket for :::9999
2024-02-20 19:51:38.212: main pid 4308: LOG:  listen address[0]: localhost
2024-02-20 19:51:38.212: main pid 4308: LOG:  Setting up socket for ::1:9898
2024-02-20 19:51:38.212: main pid 4308: LOG:  Setting up socket for 127.0.0.1:9898
2024-02-20 19:51:38.214: main pid 4308: LOG:  pgpool-II successfully started. version 4.4.2 (nurikoboshi)
2024-02-20 19:51:38.214: main pid 4308: LOG:  node status[0]: 0
2024-02-20 19:51:38.214: main pid 4308: LOG:  node status[1]: 0
2024-02-20 19:51:38.214: life_check pid 4321: LOG:  2 watchdog nodes are configured for lifecheck
2024-02-20 19:51:38.214: life_check pid 4321: LOG:  watchdog nodes ID:1 Name:"192.168.230.131:9999 Linux study_04"
2024-02-20 19:51:38.214: life_check pid 4321: DETAIL:  Host:"192.168.230.131" WD Port:9000 pgpool-II port:9999
2024-02-20 19:51:38.214: life_check pid 4321: LOG:  watchdog nodes ID:0 Name:"192.168.230.130:9999 Linux study_03"
2024-02-20 19:51:38.214: life_check pid 4321: DETAIL:  Host:"192.168.230.130" WD Port:9000 pgpool-II port:9999
2024-02-20 19:51:38.216: health_check pid 4357: LOG:  process started
2024-02-20 19:51:38.217: pcp_main pid 4354: LOG:  PCP process: 4354 started
2024-02-20 19:51:38.219: sr_check_worker pid 4355: LOG:  process started
2024-02-20 19:51:38.220: health_check pid 4356: LOG:  process started
2024-02-20 19:51:39.227: heart_beat_receiver pid 4358: LOG:  set SO_REUSEPORT option to the socket
2024-02-20 19:51:39.228: heart_beat_receiver pid 4358: LOG:  creating watchdog heartbeat receive socket.
2024-02-20 19:51:39.228: heart_beat_receiver pid 4358: DETAIL:  set SO_REUSEPORT
2024-02-20 19:51:39.228: heart_beat_sender pid 4359: LOG:  set SO_REUSEPORT option to the socket
2024-02-20 19:51:39.228: heart_beat_sender pid 4359: LOG:  creating socket for sending heartbeat
2024-02-20 19:51:39.228: heart_beat_sender pid 4359: DETAIL:  set SO_REUSEPORT

これと言ったエラーはなく、正常に立ち上がりました!

※試行錯誤したので起動失敗回数は多いですが(汗

副系のdata内を削除し、主系のdataをコピー(pg_basebackup)

データ不整合が発生した時用のものです。

scpで持ってくる方が無難かもしれませんが、PostgreSQL側に不整合関連の異常が発生した際に使えます。

su - postgres
rm -rf /var/lib/pgsql/15/data/*
pg_basebackup -R -D /var/lib/pgsql/15/data/ -h 主系IP

watchdogとpgpoolの確認

pgpool

ここではPostgreSQLのPrimary-Stanby構成が出来ているか確認します。

仮想空間(IP)内でデータを共有しレプリケーション&ロードバランスを行います。

su - postgres

-bash-4.2$ psql -h pgpoolのVIP -p 9999 -U postgres -c "show pool_nodes"
ユーザー postgres のパスワード:
 node_id |    hostname     | port | status | pg_status | lb_weight |  role   | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | la
st_status_change
---------+-----------------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+---
------------------
 0       | server3のIP | 5432 | up     | up        | 0.500000  | primary | primary | 0          | false             | 0                 |                   |                        | 20
24-02-20 13:08:21
 1       | server4のIP | 5432 | up     | up        | 0.500000  | standby | standby | 0          | true              | 0                 |                   |                        | 20
24-02-20 13:08:21
(2 行)

無事PRIMARY-STANBYモードになりました!

続いて主系を落としてみたところ・・・

[postgres@study_04 ~]$ psql -h 192.168.230.100 -p 9999 -U postgres -c "show pool_nodes"
ユーザー postgres のパスワード:
 node_id |    hostname     | port | status | pg_status | lb_weight |  role   | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | la
st_status_change
---------+-----------------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+---
------------------
 0       | 192.168.230.128 | 5432 | down   | down      | 0.500000  | standby | unknown | 0          | false             | 0                 |                   |                        | 20
24-02-20 14:28:21
 1       | 192.168.230.129 | 5432 | up     | up        | 0.500000  | primary | primary | 0          | true              | 0                 |                   |                        | 20
24-02-20 14:28:21
(2 行)

OK!そして元に戻すと

ユーザー postgres のパスワード:
 node_id |    hostname     | port | status | pg_status | lb_weight |  role   | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | la
st_status_change
---------+-----------------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+---
------------------
 0       | 192.168.230.128 | 5432 | down   | up        | 0.500000  | standby | primary | 0          | false             | 0                 |                   |                        | 20
24-02-20 14:28:21
 1       | 192.168.230.129 | 5432 | up     | up        | 0.500000  | primary | primary | 0          | true              | 0                 |                   |                        | 20
24-02-20 14:28:21
(2 行)

復活はしたものの、主系statusがdownのままなので

pcp_attach_node -h localhost -U postgres -n 0
Password:
pcp_attach_node -- Command Successful

でノード復帰させます。

早速確認。

-bash-4.2$ psql -h 192.168.230.100 -p 9999 -U postgres -c "show pool_nodes"
ユーザー postgres のパスワード:
 node_id |    hostname     | port | status | pg_status | lb_weight |  role   | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | la
st_status_change
---------+-----------------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+---
------------------
 0       | 192.168.230.128 | 5432 | up     | up        | 0.500000  | primary | primary | 0          | false             | 0                 |                   |                        | 20
24-02-20 14:34:43
 1       | 192.168.230.129 | 5432 | up     | up        | 0.500000  | standby | primary | 0          | true              | 56                |                   |                        | 20
24-02-20 14:33:18
(2 行)

無事元通り!主系もPrimaryに復帰しました。

watchdog

こちらはpgpool同士の監視です。

-bash-4.2$ pcp_watchdog_info -p 9898 -U postgres -h localhost -v
Password:
Watchdog Cluster Information
Total Nodes              : 2
Remote Nodes             : 1
Member Remote Nodes      : 1
Alive Remote Nodes       : 1
Nodes required for quorum: 1
Quorum state             : QUORUM EXIST
Local node escalation    : YES
Leader Node Name         : 192.168.230.130:9999 Linux study_03
Leader Host Name         : 192.168.230.130

Watchdog Node Information
Node Name         : 192.168.230.130:9999 Linux study_03
Host Name         : 192.168.230.130
Delegate IP       : 192.168.230.100
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 4
Status Name       : LEADER
Membership Status : MEMBER

Node Name         : 192.168.230.131:9999 Linux study_04
Host Name         : 192.168.230.131
Delegate IP       : 192.168.230.100
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 7
Status Name       : STANDBY
Membership Status : MEMBER

主系を落として確認

[root@study_04 pgpool]# pcp_watchdog_info -p 9898 -v -U postgres -h localhost
Password:
Watchdog Cluster Information
Total Nodes              : 2
Remote Nodes             : 1
Member Remote Nodes      : 1
Alive Remote Nodes       : 0
Nodes required for quorum: 1
Quorum state             : QUORUM IS ON THE EDGE
Local node escalation    : YES
Leader Node Name         : 192.168.230.131:9999 Linux study_04
Leader Host Name         : 192.168.230.131

Watchdog Node Information
Node Name         : 192.168.230.131:9999 Linux study_04
Host Name         : 192.168.230.131
Delegate IP       : 192.168.230.100
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 4
Status Name       : LEADER
Membership Status : MEMBER

Node Name         : 192.168.230.130:9999 Linux study_03
Host Name         : 192.168.230.130
Delegate IP       : 192.168.230.100
Pgpool port       : 9999
Watchdog port     : 9000
Node priority     : 1
Status            : 10
Status Name       : SHUTDOWN
Membership Status : MEMBER

[root@study_04 pgpool]#

LEADERが変わりました!



まとめ

さて、ひとまずpgpoolを入れることが出来ました。

postgresql側でのやり方次第でエラーが発生することもあり、実にデリケートなミドルとなっております。

※設定も時間掛かりますし・・・~hba.confとパスワード設定を意識しないとエラー多発しますし・・・

そして非常に便利なレプリケーション機能、直接DBアクセス⇒更新で主・副に同期されました!

psql DB名
insert into テーブル名 values (更新レコード);

特にポート「9999」の指定は不要です。手間がかかるだけあって、機能は便利となっております。

同じように構築していて、詰まっている方の参考になれば幸いです!

pgpool設定値をgitに格納しました


  • VMware × CentOS関連索引

※中山テックに掲載しているゲーム画像の著作権、商標権、その他知的財産権は、当該コンテンツの提供元に帰属します


おすすめの記事