PostgreSQLのレプリケーション設定

PostgreSQLのドキュメントや他のサイトでもすでに設定例が掲載されていますが自分用のメモとして残します。
本設定はyum経由でPostgreSQL9.2をインストールしていることを前提とているので、もし参考にする場合は以前の記事に従ってPostgreSQL9.2をインストールしてください。

■基本的な構成
マスターサーバ1台、スレーブサーバ2台。
マスタサーバはスレーブサーバ1台と同期レプリケーションを行い、もう1台とは非同期レプリケーションを行う。

■マスタ側の設定
レプリケーション用のユーザ作成


$psql -U postgres
CREATE ROLE レプリケーション用ユーザ LOGIN REPLICATION PASSWORD 'xxx';

PostgreSQLのdataディレクトリ配下にある設定ファイルをそれぞれ以下のように設定する。
(9.2をyum経由でインストールした場合は/var/lib/pgsql/9.2/data配下)
postgresql.confの設定


vi postgresql.conf
wal_level = hot_standby
fsync = on
synchronous_commit = on
wal_sync_method = fsync

max_wal_senders = 3 # スレーブ数+1
wal_keep_segments = 8
replication_timeout = 60s
synchronous_standby_names = '同期スレーブサーバのホスト名(複数指定する場合は","で区切る)'

synchronous_standby_namesはスレーブ側のapplication_nameと一致させること。
synchronous_commitオプションでレプリケーションの同期方式を設定しるのですが、設定可能な方式は以下の4通りのようです。


on:マスタとスレーブでWALのディスク書込みまでを同期する
remote_write:マスタはディスク書込みまで同期するがスレーブはメモリ書込みまでを同期
local:マスタは同期するがスレーブは非同期
off:完全非同期

pg_hba.confの設定
スレーブからのアクセス設定を行う。


vi pg_hba.conf
[個別に設定する場合]
host replication レプリケーション用ユーザ スレーブのIP/32 password

[同一ネットワーク内を対象とする場合]
host replication レプリケーション用ユーザ xxx.yyy.zzz.0/24 password

それぞれのネットワーク環境によって適切に設定すること。
同一ネットワーク内で複数台構成する場合はxxx.yyy.zzz.0/24などとする方が楽。

マスター側のPostgreSQLの起動


service postgresql-9.2 start (既に起動済みの場合はrestart)

スレーブ設定の前に適当なDBの作成とテーブルの作成を行っても良い。

■スレーブ側の設定
pg_basebackupでマスターのベースバックアップをスレーブ側に展開する。(マスタ側にデータベースなどを作成している場合は、すべてのスレーブで実施すること。)
実施前に/var/lib/pgsql/9.2配下のdataディレクトリを削除もしくは退避させておくこと。特に、postgresql.confとpg_hba.confは退避させておくことをおすすめします。


pg_basebackup -h マスタサーバ -p ポート番号 -U [レプリケーション用ユーザ] -D /var/lib/pgsql/9.2/data --xlog --progress --verbose

pg_basebackupはストリーミング・レプリケーションに依存したツールらしく、ユーザにレプリケーション用のユーザを指定する必要があります。ユーザを指定しない場合はpostgresユーザで実行されるようですが、今回の例ではマスタ側のpg_hba.confにレプリケーション用のユーザにpostgresを指定していないためエラーとなります。

postgresql.confの設定
pg_basebackupによりマスタサーバのpostgresql.confがスレーブにバックアップされているため、それを直接修正する。


hot_standby = on
↓以下3つをコメントアウト(必要ないかも)
#max_wal_senders = 3
#wal_keep_segments = 8
#replication_timeout = 60s

↓synchronous_standby_namesを無効化
#synchronous_standby_names = '' #無効化

recovery.confの設定
recovery.confのサンプルをコピー


cp /usr/pgsql-9.2/share/recovery.conf.sample /var/lib/pgsql/9.2/data/recovery.conf

vi recovery.conf
standby_mode = on
primary_conninfo = 'host=マスタサーバのホスト名 port=ポート番号 user=[レプリケーション用ユーザ] password=xxx application_name=スレーブサーバ名'

各スレーブを起動しレプリケーションの状態を確認


psql -U postgres
select application_name, state, sync_state from pg_stat_replication;
application_name | state | sync_state
------------------+-----------+------------
slave1 | streaming | sync
slave2 | streaming | async

application_nameはrecovery.confで設定した名前が表示される。

■カスケードレプリケーション
カスケード型のレプリケーションの設定方法です。
マスタサーバとスレーブサーバ1が同期レプリケーションを行い、スレーブサーバ1とスレーブサーバ2が非同期レプリケーションを行うようにします。なおカスケード時のスタンバイサーバへの接続は現状非同期のみののようです。

なお本設定例は先に述べたレプリケーションの設定との差分となる部分のみを示します。

構成イメージ


master ---> slave1 ---> slave2
同期 非同期

マスタサーバとスレーブサーバ1のpostgresql.confを以下のように設定


max_wal_senders = 2 #スレーブ数+1

#スレーブサーバ1で以下の設定をコメントアウトしている場合はコメントを外してください。
wal_keep_segments = 8
replication_timeout = 60s

スレーブサーバ2のrecovery.confを以下のように設定


primary_conninfo = 'host=スレーブサーバ1のホスト名 port=ポート番号 user=[レプリケーション用ユーザ] password=xxx application_name=スレーブサーバ2名'

マスタサーバ、スレーブサーバ1、スレーブサーバ2の順番に起動し状態を確認

マスタサーバで状態確認


psql -U postgres
select application_name, state, sync_state from pg_stat_replication;
application_name | state | sync_state
------------------+-----------+------------
slave1 | streaming | sync

スレーブサーバ1で状態確認


psql -U postgres
select application_name, state, sync_state from pg_stat_replication;
application_name | state | sync_state
------------------+-----------+------------
slave2 | streaming | async