PostgreSQL 9.0でストリーミングレプリケーションとホットスタンバイの設定
目次
概要
PostgreSQLのバージョン9.0から標準の高可用性、負荷分散機能として『ストリーミングレプリケーション』がサポートされました。 9.0以降バージョンが上がる度に徐々に機能が改善され、設定手順も便利に変わってきますが、一番ベーシックな9.0での手順を紹介します。
ストリーミングレプリケーションは2台のPostgreSQLを利用してアクティブ/スタンバイ構成をとります。 アクティブ側で更新された情報をスタンバイ側に転送し、同様に更新することで2台のPostgreSQLのデータベースを同じに保ちます。
ホットスタンバイ機能はスタンバイ側のPostgreSQLでデータの参照許可する機能です。 参照のみで更新することはできません。
構成
サーバ構成
OSバージョン
Red Hat Enterprise Linux 5.9 x86_64
ソフトウェア・パッケージ一覧
postgresql90-9.0.13-1PGDG.rhel5.x86_64.rpm
postgresql90-libs-9.0.13-1PGDG.rhel5.x86_64.rpm
postgresql90-server-9.0.13-1PGDG.rhel5.x86_64.rpm
環境構築
インストール
ストリーミングレプリケーションの設定を行うに当たって、事前に PostgreSQL 9.0のインストールと初期設定と WALの設定に沿って設定が完了している前提とします。
その他ストリーミングレプリケーションの機能を実装するに当たって 追加でインストールしなければならないものはありません。
アクティブ側PostgreSQLの設定
データベースクラスタ($PGDATA環境変数)は以下の通りとします。
-bash-3.2$ echo $PGDATA /data/pgdata1
WAL転送プロセスの設定
postgresql.confファイルをエディタで編集します。 スタンバイ側からのWALの送信要求に応えるプロセスの数を設定します。
-bash-3.2$ cd /data/pgdata1/ -bash-3.2$ vi postgresql.conf
※以下、該当箇所のみ変更※ #max_wal_senders = 0 # max number of walsender processes ↓変更 max_wal_senders = 2 # max number of walsender processes
ホストベース認証の設定
スタンバイ側からのレプリケーション要求を許可するための認証設定を行います。 スタンバイ側(IPアドレス/ネットマスクは192.168.0.77/24)からTCP/IP接続で postgresユーザで接続してきた場合は信頼(許可)します。
-bash-3.2$ vi pg_hba.conf
※ファイルの末尾に追加※
host replication postgres 192.168.0.77/24 trust
PostgreSQLインスタンスの再起動
一通り必要な設定が終わったらPostgreSQLインスタンスを再起動します。
-bash-3.2$ pg_ctl restart -w サーバ停止処理の完了を待っています....完了 サーバは停止しました サーバの起動完了を待っています....完了 サーバ起動完了
ベースバックアップ前のWALの開始位置記録
ベースバックアップ取得前にpg_start_backup()を実行します。 ベースバックアップ中に生成されたWALを後から追いつきで適用するために、 WALの開始位置を記録します。
-bash-3.2$ psql -c "select pg_start_backup('20140525_Backup')" pg_start_backup ----------------- 0/2B000020 (1 行) -bash-3.2$
ベースバックアップの取得
データベースクラスタのベースバックアップを取得します。 取得にはLinuxのtarコマンドなどを使用します。 必ずしもアーカイブする必要はありませんが、スタンバイ側へファイルを 転送しやすくするためにアーカイブしています。
-bash-3.2$ cd /data/ -bash-3.2$ tar zcvf /bkup/20140525_pgdata1.tar.gz ./pgdata1 ./pgdata1/ ./pgdata1/postmaster.opts ./pgdata1/pg_hba.conf ./pgdata1/pg_notify/ ./pgdata1/pg_notify/0000 (中略) ./pgdata1/pg_multixact/members/0000 ./pgdata1/pg_multixact/offsets/ ./pgdata1/pg_multixact/offsets/0000 ./pgdata1/pg_clog/ ./pgdata1/pg_clog/0000 -bash-3.2$ ls -l /bkup/ 合計 14340 -rw-r--r-- 1 postgres postgres 3006239 5月 25 15:26 20140525_pgdata1.tar.gz ←ベースバックアップファイル drwxr-xr-x 3 postgres postgres 4096 5月 25 10:32 pgdata1
ベースバックアップ後のWALの終了位置記録
ベースバックアップの取得が終わったら、ベースバックアップ中に生成された WALの終了位置を記録します。
-bash-3.2$ psql -c "select pg_stop_backup()" NOTICE: pg_stop_backup complete, all required WAL segments have been archived pg_stop_backup ---------------- 0/2B0000D8 (1 行) -bash-3.2$
スタンバイ側PostgreSQLの設定
これからはスタンバイ側のPostgreSQLの設定を行います。 PostgreSQLのインストールが完了している状態で、 データベースクラスタの作成(initdb)は実行されていない状態とします。 データベースクラスタ作成済みでも構いませんが、 使用しないためPostgreSQLインスタンスを停止して、データベースクラスタは 削除しておいてください。
構成としてはデータベースクラスタのパスはアクティブ側と同じとします (異なっていても構いませんが手順は適宜読み換えてください)。
-bash-3.2$ echo $PGDATA /data/pgdata1
アクティブ側で取得したベースバックアップの転送
アクティブ側で取得したベースバックアップをscpコマンドを使って スタンバイ側にコピーします。rsync等を使ってコピーしても構いません。
-bash-3.2$ cd /bkup/
-bash-3.2$ scp -p root@192.168.0.75:/bkup/20140525_pgdata1.tar.gz .
root@192.168.0.75's password: ←rootユーザのパスワードを入力
20140525_pgdata1.tar.gz 100% 2931KB 2.9MB/s 00:00
-bash-3.2$ ls -l
合計 8724
-rw-r--r-- 1 postgres postgres 3001551 5月 25 13:29 20140525_pgdata1.tar.gz
ベースバックアップの展開
ベースバックアップのtar.gzを$PGDATAの位置に展開します。
-bash-3.2$ cd /data/
-bash-3.2$ tar zxvf /bkup/20140525_pgdata1.tar.gz
./pgdata1/
./pgdata1/postgresql.conf.bk20140525a
./pgdata1/postmaster.opts
./pgdata1/pg_hba.conf
./pgdata1/pg_notify/
./pgdata1/pg_notify/0000
(中略)
./pgdata1/pg_multixact/members/0000
./pgdata1/pg_multixact/offsets/
./pgdata1/pg_multixact/offsets/0000
./pgdata1/pg_clog/
./pgdata1/pg_clog/0000
-bash-3.2$ ls -l
合計 4
drwx------ 13 postgres postgres 4096 5月 25 15:47 pgdata1
ホットスタンバイの設定
ベースバックアップとしてアクティブ側からコピーした postgresql.confファイルをスタンバイ用に編集します。 まず、PostgreSQLインスタンスが接続をリスニングするIPアドレスを スタンバイサーバのIPアドレスに変更します。 また、ホットスタンバイの設定を有効にします。 これによりアクティブ側での変更を反映させている最中も SQLによる参照を許可します。
-bash-3.2$ cd /data/pgdata1/ -bash-3.2$ vi postgresql.conf
※以下、該当箇所のみ変更※ listen_addresses = '192.168.0.75' ↓変更 listen_addresses = '192.168.0.77'
#hot_standby = off # "on" allows queries during recovery
↓変更
hot_standby = on # "on" allows queries during recovery
ホストベース認証の設定
アクティブ側でレプリケーション要求を許可するための設定を行いましたが、 スタンバイ側では不要ですので該当行を削除します。
-bash-3.2$ vi pg_hba.conf
(前略) local all postgres ident local all all md5 host all all 192.168.0.0/24 md5 host replication postgres 192.168.0.77/24 trust ←削除
アクティブ側からWALを受信するための設定
レプリケーションの際に、アクティブ側からWALを取得するための設定を行います。
-bash-3.2$ vi recovery.conf
※ファイルを新規作成※
standby_mode = 'on'
primary_conninfo = 'host=192.168.0.75 port=5432 user=postgres password=postgres'
restore_command = 'scp "192.168.0.75:/bkup/pgdata1/pg_arch/%f" "%p"'
trigger_file = '/data/pgdata1/trigger_file'
PostgreSQLインスタンスの起動
スタンバイ側の設定が終わったら、PostgreSQLインスタンスを起動します。
-bash-3.2$ pg_ctl start -w pg_ctl: 他のサーバが動作中の可能性がありますが、とにかくpostmasterの起動を試みます。 サーバの起動完了を待っています...完了 サーバ起動完了
ややエラーっぽいメッセージが出力されていますが、 ログの最後に『streaming replication successfully connected to primary』と 出力されていれば成功です。
-bash-3.2$ cat /data/pgdata1/pg_log/postgresql-20140525.log
(前略)
2014-05-25 15:47:44 JST [4956] LOG: database system was interrupted; last known up at 2014-05-25 15:24:56 JST
2014-05-25 15:47:44 JST [4956] LOG: restored log file "00000002.history" from archive
2014-05-25 15:47:44 JST [4956] LOG: entering standby mode
2014-05-25 15:47:45 JST [4956] LOG: restored log file "00000002000000000000002B" from archive
2014-05-25 15:47:45 JST [4956] LOG: redo starts at 0/2B000020
2014-05-25 15:47:45 JST [4956] LOG: consistent recovery state reached at 0/2B0000D8
2014-05-25 15:47:45 JST [4954] LOG: database system is ready to accept read only connections
scp: /bkup/pgdata1/pg_arch/00000002000000000000002C: No such file or directory
2014-05-25 15:47:45 JST [4956] LOG: unexpected pageaddr 0/25000000 in log file 0, segment 44, offset 0
scp: /bkup/pgdata1/pg_arch/00000002000000000000002C: No such file or directory
2014-05-25 15:47:45 JST [4968] LOG: streaming replication successfully connected to primary
動作テスト
アクティブ側での確認
アクティブ側で現在のトランザクションログの書き込み位置を確認します。
-bash-3.2$ psql -c "select pg_current_xlog_location()" pg_current_xlog_location -------------------------- 0/2C0002F0 (1 行) -bash-3.2$
スタンバイ側での確認
続いてスタンバイ側でストリーミングレプリケーションにより 受信して書き込まれたトランザクションログの最後の位置を確認します。
-bash-3.2$ psql -c "select pg_last_xlog_receive_location()" pg_last_xlog_receive_location ------------------------------- 0/2C0002F0 (1 行) -bash-3.2$
上記のように表示された値が一致していればストリーミングレプリケーションは 正常に動作しています。もし一致しない場合は数分待ってから再度2台で実行してみてください。 なお、頻繁にデータベースが更新されている場合は、かなり素早く2台で実行しないと 値が一致しないので、できるだけ更新が少ない(理想的には全くない)状態で実行してください。
また、ホットスタンバイが有効になっているか、 スタンバイ側でいくつかSQLを実行してみてください。 データを参照(select)できれば成功です。
-bash-3.2$ psql -U user1 testdb1
ユーザ user1 のパスワード:
psql (9.0.13)
"help" でヘルプを表示します.
testdb1=> \dt
リレーションの一覧
スキーマ | 名前 | 型 | 所有者
----------+-----------+----------+--------
public | tbl1 | テーブル | user1
public | trn_event | テーブル | user1
public | trn_group | テーブル | user1
public | trn_point | テーブル | user1
public | trn_user | テーブル | user1
(5 行)
testdb1=> select * from trn_user;
user_id | user_name | nick_name | login_name | password | authority | birthday | hometown |
tel | email | zip_code | address | group_id | create_date
| delete_date | last_update
---------+--------------+--------------+------------+-----------+-----------+----------+----------+
------------+-----------------------------+----------+--------------+----------+-------------------
-+---------------------+---------------------
0 | 管理者 | 管理者 | admin | admin | 1 | | |
| | | | 0 | 2011-07-16 23:32:0
(後略)
testdb1=> \q
-bash-3.2$