--- title: VMware Tanzu for Postgres 18.2をPatroniによるHA構成でRocky Linuxにインストールするメモ summary: この記事ではOrbStack上のRocky Linux 9にVMware Tanzu for Postgres 18.2をPatroni HA構成でインストールし、Etcd・HAProxy設定とフェイルオーバー検証まで手順を紹介します。 tags: ["Tanzu", "PostgreSQL", "Rocky", "Patroni", "Etcd", "HAProxy"] categories: ["Middleware", "RDBMS", "PostgreSQL", "Patroni"] date: 2026-02-26T11:37:26.067Z updated: 2026-02-26T11:37:26.066Z --- [VMware Tanzu for Postgres](https://techdocs.broadcom.com/us/en/vmware-tanzu/data-solutions/tanzu-for-postgres/18-2/tnz-postgres/index.html) 18.2をRocky Linux 9上にPatroniによるHA構成でインストールするメモです。 本記事では[OrbStack](https://orbstack.dev/)のLinux Machineを使用して、以下の構成を構築します。HAProxy以外は[公式ドキュメント](https://techdocs.broadcom.com/us/en/vmware-tanzu/data-solutions/tanzu-for-postgres/18-2/tnz-postgres/bp-patroni-setup.html)の推奨構成です。 * Etcdクラスター: 3ノード (`etcd-1`, `etcd-2`, `etcd-3`) * PostgreSQL + Patroniクラスター: 3ノード (`postgres-1`, `postgres-2`, `postgres-3`) * HAProxyロードバランサー: 1ノード (`haproxy`) OrbStackの仕様上、Firewallは無効化されている前提で進めます。必要に応じて適宜ポートを開放してください。 **目次** ### VMware Tanzu for Postgresのダウンロード [Broadcom Support](https://support.broadcom.com)にログインして、[VMware Tanzu for Postgresのダウンロードページ](https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware%20Tanzu%20for%20Postgres)にアクセスします。 最新バージョンを選択します。 ![image](https://s3.ik.am/ikam/_/1771999989178_pasted-image.png) "I agree to the Terms and Conditions"にチェックを入れて、 ![image](https://s3.ik.am/ikam/_/1769080281957_pasted-image.png) EL9用のインストーラーを`~/Downloads`にダウンロードします。 ![image](https://s3.ik.am/ikam/_/1772000093245_pasted-image.png) ```bash cd ~/Downloads mkdir -p vmware-postgres-18.2.0 unzip -d vmware-postgres-18.2.0 vmware-postgres-18.2.0.el9.x86_64.zip ``` ### Etcd クラスターの構築 PatroniはDCS(Distributed Configuration Store)としてEtcdを使用し、クラスターのリーダー選出や構成管理を行います。ここでは3ノードのEtcdクラスターを構築します。 まず、1台目のEtcd用のLinux Machineを作成してシェルに入ります。 ```bash orb create -a amd64 rocky:9 etcd-1 orb shell -m etcd-1 ``` Etcd用のシステムユーザーとグループを作成し、データディレクトリを準備します。 ```bash sudo groupadd --system etcd sudo useradd -s /sbin/nologin --system -g etcd etcd sudo mkdir -p /var/lib/etcd /etc/etcd sudo chown -R etcd:etcd /var/lib/etcd sudo chmod 750 /var/lib/etcd ``` VMware Tanzu for Postgresに同梱されているEtcdのRPMパッケージをインストールします。OrbStackのLinux Machineではホストの`/Users`がマウントされているため、ホスト側でダウンロードしたファイルにそのままアクセスできます。 ```bash cd /Users/$USER/Downloads/vmware-postgres-18.2.0 sudo dnf install -y vmware-postgres-etcd-3.6.7-2.el9.x86_64.rpm ``` Etcdをsystemdサービスとして管理するためのユニットファイルを作成します。 ```bash sudo tee /etc/systemd/system/etcd.service <<'EOF' [Unit] Description=etcd distributed reliable key-value store After=network-online.target Wants=network-online.target [Service] Type=notify User=etcd Group=etcd ExecStart=/opt/vmware/etcd/bin/etcd --config-file /etc/etcd/etcd.yaml Restart=on-failure RestartSec=10s LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload ``` 1台目の設定が完了したので、シェルを抜けます。 ```bash exit ``` `orb clone`で1台目のマシンをクローンして、残り2台のEtcdノードを作成します。 ```bash orb clone etcd-1 etcd-2 orb clone etcd-1 etcd-3 ``` クローンしたマシンを起動します。 ```bash orb start etcd-2 orb start etcd-3 ``` 各ノードのIPアドレスを確認します。このIPアドレスは後ほどEtcdの設定ファイルで使用します。 ```bash $ orb list NAME STATE DISTRO VERSION ARCH SIZE IP ---- ----- ------ ------- ---- ---- -- etcd-1 running rockylinux 9 amd64 192.168.139.78 etcd-2 running rockylinux 9 amd64 192.168.139.203 etcd-3 running rockylinux 9 amd64 192.168.139.214 ``` `generate_etcd_configs.sh` を作成して、各ノードのetcd設定ファイルを自動生成します。 ```bash #!/bin/bash # ノード定義 hosts=("etcd-1" "etcd-2" "etcd-3") addrs=("192.168.139.78" "192.168.139.203" "192.168.139.214") count=${#hosts[@]} for i in "${!hosts[@]}"; do instance_hostname="${hosts[$i]}" instance_address="${addrs[$i]}" # 残り2ノードをa, bとして取得 others=() for j in "${!hosts[@]}"; do [[ $i -ne $j ]] && others+=($j) done etcd_hostname_a="${hosts[${others[0]}]}" etcd_address_a="${addrs[${others[0]}]}" etcd_hostname_b="${hosts[${others[1]}]}" etcd_address_b="${addrs[${others[1]}]}" cat > "${instance_hostname}.yaml" << EOF name: '${instance_hostname}' data-dir: /var/lib/etcd listen-peer-urls: 'http://${instance_address}:2380' listen-client-urls: 'http://${instance_address}:2379,http://127.0.0.1:2379' initial-advertise-peer-urls: 'http://${instance_address}:2380' advertise-client-urls: 'http://${instance_address}:2379' initial-cluster: '${instance_hostname}=http://${instance_address}:2380,${etcd_hostname_a}=http://${etcd_address_a}:2380,${etcd_hostname_b}=http://${etcd_address_b}:2380' initial-cluster-state: 'new' initial-cluster-token: 'etcd-cluster' EOF echo "Generated: ${instance_hostname}.yaml" done ``` スクリプトを実行して設定ファイルを生成します。 ```bash chmod +x generate_etcd_configs.sh ./generate_etcd_configs.sh ``` 生成された設定ファイルを各ノードに配布します。 ```bash for i in $(seq 1 3); do orb push etcd-${i}.yaml -m etcd-${i} /tmp/ orb shell -m etcd-${i} sudo mv /tmp/etcd-${i}.yaml /etc/etcd/etcd.yaml orb shell -m etcd-${i} sudo chown etcd:etcd /etc/etcd/etcd.yaml done ``` 全ノードでEtcdサービスを起動します。 ```bash for i in $(seq 1 3); do orb shell -m etcd-${i} sudo systemctl enable etcd orb shell -m etcd-${i} sudo systemctl start etcd done ``` 各ノードでEtcdサービスが正常に起動していることを確認します。 ```bash for i in $(seq 1 3); do orb shell -m etcd-${i} sudo systemctl status etcd -n 0 done ``` ``` ● etcd.service - etcd distributed reliable key-value store Loaded: loaded (/etc/systemd/system/etcd.service; enabled; preset: disabled) Drop-In: /run/systemd/system/service.d └─zzz-lxc-service.conf Active: active (running) since Thu 2026-02-26 16:37:52 JST; 1min 40s ago Main PID: 777 (etcd) Tasks: 18 (limit: 617192) Memory: 83.9M (peak: 86.0M) CPU: 2.247s CGroup: /system.slice/etcd.service └─777 /opt/vmware/etcd/bin/etcd --config-file /etc/etcd/etcd.yaml ● etcd.service - etcd distributed reliable key-value store Loaded: loaded (/etc/systemd/system/etcd.service; enabled; preset: disabled) Drop-In: /run/systemd/system/service.d └─zzz-lxc-service.conf Active: active (running) since Thu 2026-02-26 16:37:52 JST; 1min 40s ago Main PID: 430 (etcd) Tasks: 19 (limit: 617192) Memory: 61.1M (peak: 62.2M) CPU: 2.081s CGroup: /system.slice/etcd.service └─430 /opt/vmware/etcd/bin/etcd --config-file /etc/etcd/etcd.yaml ● etcd.service - etcd distributed reliable key-value store Loaded: loaded (/etc/systemd/system/etcd.service; enabled; preset: disabled) Drop-In: /run/systemd/system/service.d └─zzz-lxc-service.conf Active: active (running) since Thu 2026-02-26 16:37:52 JST; 1min 40s ago Main PID: 432 (etcd) Tasks: 18 (limit: 617192) Memory: 64.4M (peak: 65.4M) CPU: 2.675s CGroup: /system.slice/etcd.service └─432 /opt/vmware/etcd/bin/etcd --config-file /etc/etcd/etcd.yaml ``` Etcdノードの1つにログインして、クラスターの状態を確認します。 ```bash orb shell -m etcd-1 ``` `etcdctl`コマンドでクラスター内の全エンドポイントのヘルスチェックを行います。 ```bash /opt/vmware/etcd/bin/etcdctl endpoint health --cluster -w table ``` ``` +-----------------------------+--------+-------------+-------+ | ENDPOINT | HEALTH | TOOK | ERROR | +-----------------------------+--------+-------------+-------+ | http://192.168.139.78:2379 | true | 6.363441ms | | | http://192.168.139.214:2379 | true | 26.989624ms | | | http://192.168.139.203:2379 | true | 28.053309ms | | +-----------------------------+--------+-------------+-------+ ``` 各ノードのステータス(バージョン、DB サイズ、リーダー情報など)を確認します。 ```bash /opt/vmware/etcd/bin/etcdctl endpoint status --cluster -w table ``` ``` +-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | ENDPOINT | ID | VERSION | STORAGE VERSION | DB SIZE | IN USE | PERCENTAGE NOT IN USE | QUOTA | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | DOWNGRADE TARGET VERSION | DOWNGRADE ENABLED | +-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | http://192.168.139.203:2379 | 19506a455bdfcf4f | 3.6.7 | 3.6.0 | 20 kB | 16 kB | 20% | 2.1 GB | false | false | 2 | 11 | 11 | | | false | | http://192.168.139.78:2379 | 9b774fa21f98412c | 3.6.7 | 3.6.0 | 20 kB | 16 kB | 20% | 2.1 GB | false | false | 2 | 11 | 11 | | | false | | http://192.168.139.214:2379 | a4d6bd99f689a01b | 3.6.7 | 3.6.0 | 20 kB | 16 kB | 20% | 2.1 GB | true | false | 2 | 11 | 11 | | | false | +-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ ``` 3ノード全てが`HEALTH: true`であれば、Etcdクラスターは正常に稼働しています。 ### Postgres / Patroni クラスターの構築 続いて、PostgreSQLとPatroniをインストールしてHA構成のPostgreSQLクラスターを構築します。 まず、1台目のPostgres用のLinux Machineを作成してシェルに入ります。 ```bash orb create -a amd64 rocky:9 postgres-1 orb shell -m postgres-1 ``` ドキュメントには書いてありませんでしたが、VMware Tanzu for Postgresのインストールには`libssh2`パッケージが必要でした。 `libssh2`パッケージをインストールするにはEPEL(Extra Packages for Enterprise Linux)リポジトリを有効化する必要があります。 ```bash sudo dnf install epel-release -y ``` メタデータを更新します。 ```bash sudo dnf clean all sudo dnf makecache ``` `libssh2`(その他、あると便利な)パッケージをインストールします。 ```bash sudo dnf install libssh2 which lsof vim bind-utils -y ``` VMware Tanzu for Postgres 18のRPMパッケージをインストールします。 ```bash cd /Users/$USER/Downloads/vmware-postgres-18.2.0 sudo dnf install ./vmware-postgres18-18.2-1.el9.x86_64.rpm ./vmware-postgres18-libs-18.2-1.el9.x86_64.rpm -y ``` PatroniはPythonで実装されているため、Python3と`pip`をインストールします。 ```bash sudo dnf install -y python3 python3-pip ``` Patroniが必要とするPythonライブラリの一覧を`requirements.txt`に記載します。 ```bash cat < /tmp/requirements.txt PyYAML click>=4.1 prettytable>=0.7 psutil>=2.0.0 python-dateutil python-etcd>=0.4.3,<0.5 requests six >= 1.7 urllib3>=1.19.1,!=1.21 ydiff>=1.2.0 cdiff>=1.0 EOF ``` `postgres`ユーザーとしてPythonライブラリをインストールします。 ```bash sudo -u postgres pip3 install --user -r /tmp/requirements.txt ``` PatroniのRPMパッケージをインストールします。 ```bash cd /Users/$USER/Downloads/vmware-postgres-18.2.0 sudo dnf install ./vmware-postgres-patroni-4.1.0-4.el9.x86_64.rpm -y ``` Patroniがクラスターを初期化した直後に実行されるブートストラップスクリプトを作成します。このスクリプトでは、`postgres`ユーザーのパスワード設定、レプリケーション用ユーザー(`replicator`)の作成、および`pg_rewind`用ユーザー(`rewind_user`)の作成と必要な権限付与を行います。パスワードは適宜変更してください。 ```bash sudo -u postgres tee /etc/patroni/post_bootstrap.sh <<'EOF' #!/bin/bash /opt/vmware/postgres/18/bin/psql -U postgres < "patroni-${instance_name}.yaml" < /dev/null global log /dev/log local0 log /dev/log local1 notice pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon defaults mode tcp log global option tcplog option dontlognull option tcp-check retries 3 timeout connect 5s timeout client 30m timeout server 30m timeout check 5s maxconn 3000 listen stats bind *:7000 mode http stats enable stats uri / stats refresh 10s stats show-node stats auth admin:admin listen primary bind *:5000 option httpchk GET /primary http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions $(for i in "${!addrs[@]}"; do echo " server postgres-$((i+1)) ${addrs[$i]}:5432 check port 8008"; done) listen replicas bind *:5001 option httpchk GET /replica http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions $(for i in "${!addrs[@]}"; do echo " server postgres-$((i+1)) ${addrs[$i]}:5432 check port 8008"; done) listen all_nodes bind *:5002 balance roundrobin option httpchk GET /health http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions $(for i in "${!addrs[@]}"; do echo " server postgres-$((i+1)) ${addrs[$i]}:5432 check port 8008"; done) EOF /opt/vmware/haproxy/sbin/haproxy -c -f /etc/haproxy/haproxy.cfg && echo "Config OK" ``` HAProxyサービスを有効化して起動します。 ```bash sudo systemctl enable haproxy sudo systemctl start haproxy ``` ログを確認すると、HAProxyがPatroniのREST APIを使ってヘルスチェックを行い、各ノードの役割に応じて振り分けが正しく機能していることがわかります。Replicaノードはprimaryポートで503を返すためDOWNとなり、LeaderノードはreplicaポートでDOWNとなることが正常な動作です。 ```bash journalctl -u haproxy -f ``` ``` Feb 26 19:20:55 haproxy haproxy[763]: Server primary/postgres-2 is DOWN, reason: Layer7 wrong status, code: 503, info: "Service Unavailable", check duration: 22ms. 2 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. Feb 26 19:20:55 haproxy haproxy[763]: Server primary/postgres-2 is DOWN, reason: Layer7 wrong status, code: 503, info: "Service Unavailable", check duration: 22ms. 2 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. Feb 26 19:20:56 haproxy haproxy[763]: Server primary/postgres-3 is DOWN, reason: Layer7 wrong status, code: 503, info: "Service Unavailable", check duration: 21ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. Feb 26 19:20:56 haproxy haproxy[763]: Server primary/postgres-3 is DOWN, reason: Layer7 wrong status, code: 503, info: "Service Unavailable", check duration: 21ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. Feb 26 19:20:56 haproxy haproxy[763]: Server replicas/postgres-1 is DOWN, reason: Layer7 wrong status, code: 503, info: "Service Unavailable", check duration: 6ms. 2 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. Feb 26 19:20:56 haproxy haproxy[763]: Server replicas/postgres-1 is DOWN, reason: Layer7 wrong status, code: 503, info: "Service Unavailable", check duration: 6ms. 2 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. ``` 全マシンの一覧を確認します。HAProxyのIPアドレス(`192.168.139.240`)がクライアントからの接続先となります。 ```bash $ orb list NAME STATE DISTRO VERSION ARCH SIZE IP ---- ----- ------ ------- ---- ---- -- etcd-1 running rockylinux 9 amd64 192.168.139.78 etcd-2 running rockylinux 9 amd64 192.168.139.203 etcd-3 running rockylinux 9 amd64 192.168.139.214 haproxy running rockylinux 9 amd64 192.168.139.240 postgres-1 running rockylinux 9 amd64 192.168.139.134 postgres-2 running rockylinux 9 amd64 192.168.139.155 postgres-3 running rockylinux 9 amd64 192.168.139.141 ``` HAProxyの統計画面(ポート7000)にブラウザからアクセスすると、各バックエンドの状態を視覚的に確認できます。 ![image](https://s3.ik.am/ikam/_/1772101442648_pasted-image.png) HAProxy経由でPostgreSQLに接続して動作を確認します。 ポート5000(primary)に接続すると、Leaderノード(`192.168.139.134`)に接続され、`pg_is_in_recovery()`が`f`(false)を返します。 ```bash $ psql postgresql://postgres:postgres@192.168.139.240:5000 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.134 | f (1 row) ``` ポート5001(replica)に接続すると、Replicaノードにラウンドロビンで接続されます。`pg_is_in_recovery()`が`t`(true)を返し、読み取り専用であることがわかります。 ```bash $ psql postgresql://postgres:postgres@192.168.139.240:5001 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.155 | t (1 row) $ psql postgresql://postgres:postgres@192.168.139.240:5001 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.141 | t (1 row) ``` ポート5002(all_nodes)に接続すると、Leader・Replica問わず全ノードにラウンドロビンで接続されます。 ```bash $ psql postgresql://postgres:postgres@192.168.139.240:5002 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.134 | f (1 row) $ psql postgresql://postgres:postgres@192.168.139.240:5002 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.155 | t (1 row) $ psql postgresql://postgres:postgres@192.168.139.240:5002 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.141 | t ``` レプリケーションが正しく動作していることを確認するため、Primaryにテーブルを作成してデータを挿入します。 ```bash psql postgresql://postgres:postgres@192.168.139.240:5000 -c " CREATE TABLE IF NOT EXISTS organization ( organization_id BIGINT PRIMARY KEY, organization_name VARCHAR(255) NOT NULL ); INSERT INTO organization(organization_id, organization_name) VALUES(1, 'foo'); INSERT INTO organization(organization_id, organization_name) VALUES(2, 'bar'); " ``` ``` CREATE TABLE INSERT 0 1 INSERT 0 1 ``` Replicaポート(5001)経由で書き込みを試みると、読み取り専用トランザクションのため正しくエラーになります。 ```bash psql postgresql://postgres:postgres@192.168.139.240:5001 -c "INSERT INTO organization(organization_id, organization_name) VALUES(3, 'baz')" ``` ``` ERROR: cannot execute INSERT in a read-only transaction ``` all_nodesポート(5002)経由で`SELECT`を実行すると、全ノードにラウンドロビンで接続され、どのノードからもレプリケーションされたデータが読み取れることを確認できます。 ```bash $ psql postgresql://postgres:postgres@192.168.139.240:5002 -c "SELECT inet_server_addr(), organization_id,organization_name from organization" inet_server_addr | organization_id | organization_name ------------------+-----------------+------------------- 192.168.139.134 | 1 | foo 192.168.139.134 | 2 | bar (2 rows) $ psql postgresql://postgres:postgres@192.168.139.240:5002 -c "SELECT inet_server_addr(), organization_id,organization_name from organization" inet_server_addr | organization_id | organization_name ------------------+-----------------+------------------- 192.168.139.155 | 1 | foo 192.168.139.155 | 2 | bar (2 rows) $ psql postgresql://postgres:postgres@192.168.139.240:5002 -c "SELECT inet_server_addr(), organization_id,organization_name from organization" inet_server_addr | organization_id | organization_name ------------------+-----------------+------------------- 192.168.139.141 | 1 | foo 192.168.139.141 | 2 | bar (2 rows) ``` ### フェイルオーバーのテスト Patroniの`switchover`コマンドを使って、手動でLeaderを切り替えてフェイルオーバーの動作を確認します。 ```bash orb shell -m postgres-1 ``` `patronictl switchover`を実行し、Leaderを`postgres-1`から`postgres-2`に切り替えます。 ```bash patronictl -c /etc/patroni/patroni.yaml switchover patroni_cluster ``` 対話的にPrimaryとCandidateを選択して実行します。 ```bash Current cluster topology + Cluster: patroni_cluster (7611092906447976897) ----+----+-------------+-----+------------+-----+ | Member | Host | Role | State | TL | Receive LSN | Lag | Replay LSN | Lag | +------------+-----------------+---------+-----------+----+-------------+-----+------------+-----+ | postgres-1 | 192.168.139.134 | Leader | running | 1 | | | | | | postgres-2 | 192.168.139.155 | Replica | streaming | 1 | 0/5053F10 | 0 | 0/5053F10 | 0 | | postgres-3 | 192.168.139.141 | Replica | streaming | 1 | 0/5053F10 | 0 | 0/5053F10 | 0 | +------------+-----------------+---------+-----------+----+-------------+-----+------------+-----+ Primary [postgres-1]: postgres-1 Candidate ['postgres-2', 'postgres-3'] []: postgres-2 When should the switchover take place (e.g. 2026-02-26T21:09 ) [now]: now Are you sure you want to switchover cluster patroni_cluster, demoting current leader postgres-1? [y/N]: y 2026-02-26 20:09:59.02874 Successfully switched over to "postgres-2" + Cluster: patroni_cluster (7611092906447976897) --+----+-------------+-----+------------+-----+ | Member | Host | Role | State | TL | Receive LSN | Lag | Replay LSN | Lag | +------------+-----------------+---------+---------+----+-------------+-----+------------+-----+ | postgres-1 | 192.168.139.134 | Replica | stopped | | unknown | | unknown | | | postgres-2 | 192.168.139.155 | Leader | running | 1 | | | | | | postgres-3 | 192.168.139.141 | Replica | running | 1 | 0/5054070 | 0 | 0/5054070 | 0 | +------------+-----------------+---------+---------+----+-------------+-----+------------+-----+ ``` しばらく待ってからクラスターの状態を確認すると、`postgres-2`がLeaderに昇格し、`postgres-1`がReplicaに降格していることがわかります。Timeline(TL)も`2`に進んでいます。 ```bash $ patronictl -c /etc/patroni/patroni.yaml list + Cluster: patroni_cluster (7611092906447976897) ----+----+-------------+-----+------------+-----+ | Member | Host | Role | State | TL | Receive LSN | Lag | Replay LSN | Lag | +------------+-----------------+---------+-----------+----+-------------+-----+------------+-----+ | postgres-1 | 192.168.139.134 | Replica | streaming | 2 | 0/50541B0 | 0 | 0/50541B0 | 0 | | postgres-2 | 192.168.139.155 | Leader | running | 2 | | | | | | postgres-3 | 192.168.139.141 | Replica | streaming | 2 | 0/50541B0 | 0 | 0/50541B0 | 0 | +------------+-----------------+---------+-----------+----+-------------+-----+------------+-----+ ``` HAProxyの統計画面でも、`postgres-2`がprimaryバックエンドでUP、`postgres-1`がreplicasバックエンドでUPに変わっていることが確認できます。 ![image](https://s3.ik.am/ikam/_/1772104269742_pasted-image.png) HAProxy経由の接続もswitchoverに追従しています。ポート5000(primary)では新しいLeaderである`postgres-2`(`192.168.139.155`)に接続され、ポート5001(replica)では`postgres-1`と`postgres-3`に接続されるようになりました。 ```bash $ psql postgresql://postgres:postgres@192.168.139.240:5000 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.155 | f (1 row) $ psql postgresql://postgres:postgres@192.168.139.240:5001 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.141 | t (1 row) $ psql postgresql://postgres:postgres@192.168.139.240:5001 -c "SELECT inet_server_addr(), pg_is_in_recovery()" inet_server_addr | pg_is_in_recovery ------------------+------------------- 192.168.139.134 | t (1 row) ``` --- OrbStackのLinux Machineを使って、VMware Tanzu for Postgres 18.2をPatroniによるHA構成でRocky Linux 9上に構築しました。 `patronictl switchover`によるフェイルオーバーでは、Leaderの切り替え後にHAProxyが自動的に新しいLeaderを検出し、クライアントからの接続先が透過的に切り替わることを確認しました。