今回はrepmgrd(repmgrのデーモン)を使用したフェールオーバの設定方法について書きます。
フェールオーバとは
冗長構成を組んでいるシステムの現用系で異常が発生した場合に、自動で待機系にサービスを切り替え、サービスを継続する仕組みです。
PostgreSQL単独の場合、マスタ・スレーブ構成で冗長化していてもマスタが故障した場合はサービス(更新処理)は停止します。そのため、システムでPostgreSQLを使用するのであれば、Pacemaker、pgpool-II、repmgr等のクラスタリングソフトと組み合わせて、障害発生時にフェールオーバが行われるようにする必要があります。
(問題があったら気づいたときに復旧するぐらいの要件であれば、クラスタリングは不要ですので要件に応じて、検討する必要があります。)
前提条件
- 「記事:repmgrによるPostgreSQLのクラスタリング」に従って、repmgrの環境構築済みである
前置きが長くなってしまいましたが、ここからフェールオーバを行うための設定と手順について説明します。
フェールオーバをするには、repmgrd(repmgrのデーモン)を使用します。
repmgrdとは、スタンバイノードで動作する管理とモニタリングデーモンです。
※マスタ、スレーブはプライマリ、スタンバイとも言ったりします。(厳密な使い分けはあると思いますが、本書では適宜読み替えてください。)
1. 各設定ファイルを修正する
1-1. postgresql.confを修正する(マスタ、スレーブで実施)
postgresql.confに以下の内容を追記します。
shared_preload_libraries = 'repmgr_funcs'
1-2. repmgr.confを修正する(マスタ、スレーブで実施)
repmgr.confに以下の内容を追記します。
failover=automatic
promote_command='repmgr standby promote -f ~/local/pg952/pgsql/etc/repmgr.conf'
follow_command='repmgr standby follow -f ~/local/pg952/pgsql/etc/repmgr.conf'
2. PostgreSQLを起動(マスタ、スレーブで実施)
$ pg_ctl -D ~/local/pg952/data start
2-1. レプリケーション状態の確認(マスタのみで実施)
起動が終わったら、マスタスレーブ間でレプリケーションが実施されているか統計情報ビュー「pg_stat_replication」を確認してください。
$ psql repmgr -c 'SELECT * FROM pg_stat_replication' -U repmgr -x
-[ RECORD 1 ]----+------------------------------
pid | 23325
usesysid | 20997
usename | repmgr
application_name | inu
client_addr | 192.168.1.2
client_hostname |
client_port | 51083
backend_start | 2016-06-01 21:35:48.240615+09
backend_xmin |
state | streaming
sent_location | 0/33000528
write_location | 0/33000528
flush_location | 0/33000528
replay_location | 0/33000528
sync_priority | 0
sync_state | async
ちゃんとstateが"streaming"になっているので、レプリケーションは開始されていますね。
2-2. repmgrでの管理状況の確認(マスタ、またはスレーブで実施)
あと、念のためにrepmgrの管理状況も確認しておきましょう。
$ psql repmgr -c 'SELECT * FROM repmgr_test.repl_nodes' -U repmgr
id | type | upstream_node_id | cluster | name | conninfo | slot_name | priority | active
----+---------+------------------+---------+------+-------------------------------------+-----------+----------+--------
1 | master | | test | neko | host=neko user=repmgr dbname=repmgr | | 100 | t
2 | standby | 1 | test | inu | host=inu user=repmgr dbname=repmgr | | 100 | t
(2 rows)
"type"と"active"を見る限り、こちらも大丈夫そうですね。
3. repmgrdの起動(スレーブのみで実施)
$ repmgrd -f ~/local/pg952/pgsql/etc/repmgr.conf --verbose -d -p ~/repmgr/repmgr.pid > ~/repmgr/repmgr.log 2>&1
repmgrdが起動できているか、repl_eventsテーブルを確認します。
$ psql repmgr -c "SELECT * FROM repl_events WHERE event = 'repmgrd_start'" -U repmgr
node_id | event | successful | event_timestamp | details
---------+---------------+------------+-------------------------------+---------
2 | repmgrd_start | t | 2016-06-01 21:52:38.552002+09 |
(1 rows)
これでrepmgrdによるフェールオーバの設定は完了です。
4. フェールオーバの動作確認
マスタを強制停止し、スレーブが自動でpromoteされるかどうか確認してみます。
$ pg_ctl -D ~/local/pg952/data -m immediate stop
4-1. スレーブのログを確認
スレーブのログを確認をtailコマンド等で確認していると以下のようなログが出力されます。
2016-06-01 22:41:04でマスタとの接続が切れた旨のログが出始めます。
しかし、1分後の2016-06-01 22:42:11にスレーブがpromoteコマンドを受け付けて新マスタに昇格しています。
2016-06-01 22:41:04.346 JST [20185] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
2016-06-01 22:41:04.346 JST [20184] LOG: invalid record length at 0/33000BF0
2016-06-01 22:41:04.351 JST [22743] FATAL: could not connect to the primary server: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
2016-06-01 22:41:09.354 JST [22746] FATAL: could not connect to the primary server: could not connect to server: Connection refused
Is the server running on host "neko" (192.168.1.1) and accepting
TCP/IP connections on port 5432?
・・・
2016-06-01 22:42:11.666 JST [20184] LOG: received promote request
2016-06-01 22:42:11.666 JST [20184] LOG: redo done at 0/33000BB8
2016-06-01 22:42:11.666 JST [20184] LOG: last completed transaction was at log time 2016-06-01 21:52:38.552805+09
2016-06-01 22:42:11.669 JST [20184] LOG: selected new timeline ID: 2
2016-06-01 22:42:11.730 JST [20184] LOG: archive recovery complete
2016-06-01 22:42:11.741 JST [20184] LOG: MultiXact member wraparound protections are now enabled
2016-06-01 22:42:11.741 JST [20186] LOG: checkpoint starting: force
2016-06-01 22:42:11.742 JST [20179] LOG: database system is ready to accept connections
2016-06-01 22:42:11.777 JST [22802] LOG: autovacuum launcher started
4-2. repmgrの管理情報を確認する
repmgrの以下の情報を確認してみます。
テーブル名 | 概要 |
---|---|
repl_nodes | repmgrで管理しているノードの情報を管理するテーブル |
repl_events | repmgrのイベント通知を記録するテーブル |
repl_nodes
$ psql repmgr -c "SELECT * FROM repl_nodes" -U repmgr
id | type | upstream_node_id | cluster | name | conninfo | slot_name | priority | active
----+--------+------------------+---------+------+-------------------------------------+-----------+----------+--------
1 | master | | test | neko | host=neko user=repmgr dbname=repmgr | | 100 | f
2 | master | | test | inu | host=inu user=repmgr dbname=repmgr | | 100 | t
(2 rows)
id=1のノードの"acrive"がfに変化しており、id=2のノードの"type"がmasterになっています!
repl_events
$ psql repmgr -c "SELECT * FROM repl_events" -U repmgr
node_id | event | successful | event_timestamp | details
---------+--------------------------+------------+-------------------------------+------------------------------------------------------------------------------
1 | master_register | t | 2016-05-23 21:34:18.076811+09 |
2 | standby_clone | t | 2016-06-01 21:35:26.533515+09 | Cloned from host 'neko', port 5432; backup method: pg_basebackup; --force: N
2 | repmgrd_start | t | 2016-06-01 21:52:38.552002+09 |
2 | standby_promote | t | 2016-06-01 22:42:13.736828+09 | node 2 was successfully promoted to master
2 | repmgrd_failover_promote | t | 2016-06-01 22:42:13.767335+09 | node 2 promoted to master; old master 1 marked as failed
(5 rows)
マスタの障害(今回は強制停止)を検知して、自動でスレーブを新マスタに昇格してくれることを確認できました。
最後に
今回はrepmgrdによるフェールオーバの設定方法と動作確認を行いました。
次はrepmgrdが検知可能な障害はなにか?どういう仕組みで動いているのか?等を確認してみようと思います。