PostgreSQL9.4でストリーミングレプリケーションする
概要
PostgreSQL9.4でストリーミングレプリケーションの構成を組んでみる
以下のような構成を作成する
- マスター1台
- スレーブ2台
マスターからスレーブに矢印を引いたところに「同期」と「非同期」とあるが、これはWALファイルをマスターからスレーブに転送した時にスレーブに書き込まれてからレスポンスを返す設定とスレーブに書き込まれたかどうか確認せずに即レスポンスを返す設定のことである。
スレーブが複数台ある場合は、全て非同期か、1台のみ同期でそれ以外が非同期しか設定が出来ない仕様になっている。
また、単純なレプリケーションの設定のみではなく以下の設定も記述する
環境
AWS EC2インスタンス上に以下のバージョンの環境を構築する。
- CentOS 7
- PostgreSQL 9.4
手順
PostgreSQL9.4のインストール
以下の記事を参照して設定する まずは1台のEC2インスタンスにインストールした後、AMIを抽出してそのイメージを元に2台インスタンスを立ち上げるのが効率的である。
レプリケーション用のユーザーを作成する
DB1でレプリケーション用のユーザーを作成する。
ユーザー名、パスワードは任意の設定でよい。
su - postgres psql CREATE USER repl_user REPLICATION PASSWORD 'XXXXX';
マスターとスレーブが接続できるように設定する
DB1のpg_hba.confに接続設定を追加する
vi /var/lib/pgsql/9.4/data/pg_hba.conf ↓記述追加 host replication repl_user 127.0.0.1/32 md5 host replication repl_user 192.168.1.1/32 md5 host replication repl_user 192.168.1.2/32 md5 host replication repl_user 192.168.1.3/32 md5
今の設定だとpostgresユーザーのみでしかpsql接続できないので、他のユーザーでも接続できるように記述を変更する
local all all peer ↓ local all all trust
これでpostgresユーザー以外でもpostgresユーザとして接続ができるようになる
$ psql -U postgres psql (9.4.1) Type "help" for help. postgres=#
postgres.confの設定
DB1のpostgres.confを設定する
vi /var/lib/pgsql/9.4/data/postgres.conf
wal_levelをhot_standbyにする
wal_level = hot_standby
レプリケーションの種類を指定する
設定値 | 意味 |
---|---|
on | 同期 |
remote_write | メモリ同期 |
local | スレーブ非同期 |
off | 完全非同期 |
synchronous_commit = on
WALファイルを送信する先の数(スレーブの数)+1に設定する
max_wal_senders = 3
同期レプリケーションするノードの名前を設定する
スレーブ側にも名前を同様の設定をする必要がある、後述にて説明する。
synchronous_standby_names = 'DB2'
WALファイルを別の場所にアーカイブするモードを有効にする。
デフォルトではWALファイルはPGDATA/pg_xlog
ディレクトリに保存されるが上限があり古いWALファイルは順次削除されていく
このままだとリカバリするときに必要なWALファイルが足りなくなる可能性があるため別のディレクトリに保存するモードを有効にする必要がある。
archive_mode = on
WALファイルをアーカイブ先のディレクトリにコピーするコマンドを設定する。
本来は物理的に別のドライブに保存する方が好ましいが試験的な環境なのでPGDATA
の配下にarchive
ディレクトリを作成し、そこにコピーするように設定する。
archive_command = 'cp -i %p /var/lib/pgsql/9.4/archive/%f'
ベースバックアップをスレーブに転送する
マスタのDB情報をスレーブのDB情報と同期させる為、マスターの情報をスレーブにコピーする
DB2(192.168.1.2)で実行
一応元々のデータをバックアップしておく $ mv /var/lib/pgsql/9.4/data /var/lib/pgsql/9.4/data.bak $ pg_basebackup -h 192.168.1.1 -U repl_user -D /var/lib/pgsql/9.4/data/ -P --xlog
DB2(192.168.1.3)で実行
一応元々のデータをバックアップしておく $ mv /var/lib/pgsql/9.4/data /var/lib/pgsql/9.4/data.bak $ pg_basebackup -h 192.168.1.1 -U repl_user -D /var/lib/pgsql/9.4/data/ -P --xlog
dataディレクトリが生成されたはずだが、一応ls -la
して所有者を確認しておく、所有者が「postgres」以外だとPostgreSQLを起動したときにパーミッションエラーで起動が出来ないのでもし違う場合はchown
で所有者を「postgres」に変更しておく。
スレーブDBの設定
recovery.confの設定
まずはサンプル用のrecovery.conf
をPGDATA
にコピーする。
$ cp /usr/pgsql-9.4/share/recovery.conf.sample /var/lib/pgsql/9.4/data/recovery.conf
コピーしてきたrecovery.conf
を編集する。
DB2の設定
$ vi /var/lib/pgsql/9.4/data/recovery.conf standby_mode = on primary_conninfo = 'host=192.168.1.1 port=5432 user=repl_user password=XXXXX application_name=DB2'
DB3の設定
$ vi /var/lib/pgsql/9.4/data/recovery.conf standby_mode = on primary_conninfo = 'host=192.168.1.1 port=5432 user=repl_user password=XXXXX application_name=DB3'
スレーブのpostgres.confの設定
$ vi /var/lib/pgsql/9.4/data/postgres.conf
hot_standby = on
マスターが落ちた時にスレーブをマスターに昇格させる時に使う設定
下記のファイルが生成された瞬間にスレーブはマスターに昇格する、ただしPostgreSQLには生死を判定する機能がないのでpgpoolなどのサードパーティを使って生死判定とトリガーファイルの自動生成を設定する必要がある。
trigger_file = '/tmp/trigger_file'
PostgreSQLを起動する
DB1、DB2、DB3を起動する
$ sudo systemctl start postgresql-9.4
レプリケーションの状態を確認する
マスタ(DB1)上で以下のクエリーを実行し確認する。
$ psql -U postgres select application_name, client_addr, backend_start, state, sync_state from pg_stat_replication;
設定が正しくされていればDB2とDB3の行が表示されるはず。