2&>1

AWSとかGCPとかGolangとかとか

Postgresql12とrepmgerで自動フェイルオーバー構成を組んだ

前回の内容でPostgresql2台でrepmgerを使ってレプリケーションを組んだので今度自動でフェイルオーバーするまでを設定します。

前回の内容↓

dev-error.hatenablog.com

設定

sudoerの編集

PG-node1とPG-node2の両方でsudoerに以下追記 postgresユーザーでパスワードなしでPostgresqlのもろもろできるようにします

Defaults:postgres !requiretty
postgres ALL = NOPASSWD: /usr/bin/systemctl stop postgresql-12.service, /usr/bin/systemctl start postgresql-12.service, /usr/bin/systemctl restart postgresql-12.service, /usr/bin/systemctl reload postgresql-12.service, /usr/bin/systemctl start repmgr12.service, /usr/bin/systemctl stop repmgr12.service

repmer.confに設定追加

PG-node1とPG-node02の「repmger.conf」に以下追記

connection_check_type='ping'
reconnect_attempts=4
reconnect_interval=8
primary_visibility_consensus=true
standby_disconnect_on_failover=true
repmgrd_service_start_command='sudo /usr/bin/systemctl start repmgr12.service'
repmgrd_service_stop_command='sudo /usr/bin/systemctl stop repmgr12.service'
ervice_start_command='sudo /usr/bin/systemctl start postgresql-12.service'
service_stop_command='sudo /usr/bin/systemctl stop postgresql-12.service'
service_restart_command='sudo /usr/bin/systemctl restart postgresql-12.service'
service_reload_command='sudo /usr/bin/systemctl reload postgresql-12.service'
monitoring_history=yes
log_status_interval=60

以下説明

connection_check_type
  • ping: PQPing() メソッドでのコネクション監視
  • connection: 新規でコネクション作成できるかで監視
  • query: 既存コネクションを利用してクエリーを投げて監視
reconnect_attempts

接続試行最大回数(デフォルト6)

reconnect_interval

接続試行間隔(秒)(デフォルト10)

primary_visibility_consensus

複数スタンバイノードがある場合、ローカルノードがプライマリーノードの状態監視するより前に他スタンバイノードからフェイルオーバーする通信が来たときに却下するかどうか。 各ノードで同一にする必要あり *翻訳間違ってる可能性あり

standby_disconnect_on_failover

フェイルオーバーするとき、WALレシーバーがプライマリから切断され、WALセグメントを受信していないこと確認してから実行するかどうか。 デフォルトで30秒待機して切断されたことを確認するのでフェイルオーバーまでの時間が増える。 各ノードで同一にする必要あり

repmgrd_service_start_command and repmgrd_service_stop_command

サービス起動コマンド

PostgreSQL Service Start/Stop/Restart Commands

サービス起動コマンド

monitoring_history

監視データを保存するかどうか

log_status_interval

repmgrデーモンがステータスメッセージを記録する秒数

repmgerデーモンの実行

PG-node1とPG-node2で以下を実行

su - postgres
/usr/pgsql-12/bin/repmgr -f /etc/repmgr/12/repmgr.conf daemon start

これがでればOK

NOTICE: executing: "sudo /usr/bin/systemctl start repmgr12.service"
NOTICE: repmgrd was successfully started

以下で状態確認 PG-node1でもPG-node2のどちらからでもOK

/usr/pgsql-12/bin/repmgr -f /etc/repmgr/12/repmgr.conf cluster event --event=repmgrd_start

こんな感じで出力

 Node ID | Name     | Event         | OK | Timestamp           | Details
---------+----------+---------------+----+---------------------+-----------------------------------------------------------
 2       | PG-Node2 | repmgrd_start | t  | 2020-04-02 10:05:52 | monitoring connection to upstream node "PG-Node1" (ID: 1)
 1       | PG-Node1 | repmgrd_start | t  | 2020-04-02 10:05:36 | monitoring cluster primary "PG-Node1" (ID: 1)

フェイルオーバーのテスト

PG-node1でPostgresqlサービスを止める

systemctl stop postgresql-12.service

クラスターの状態確認

 ID | Name     | Role    | Status    | Upstream | Location | Prio. | TLI
----+----------+---------+-----------+----------+----------+-------+-----
 1  | PG-Node1 | primary | - faild   |          | default  | 100   | 1
 2  | PG-Node2 | primary | * running |          | default  | 100   | 2

PG-node2がプライマリーになってファイルオーバーしてます

まとめ

repmgerでレプリケーションからフェイルオーバーまで行いました。

一つ重要ことですがこの構成ではVIP(バーチャルアドレス)が割当たりません。

そのためフェイルオーバー時にプライマリー側へ通信するためには一工夫必要です。 postgresql10以降であれば「libpq」ライブラリをつかうことでなんとかなるらしい。(未確認)

個人的にpgpoolでやるのがやっぱり安定ですね。

参照

How to Automate PostgreSQL 12 Replication and Failover with repmgr - Part 2 - 2ndQuadrant | PostgreSQL