OSS Fan ~OSSでLinuxサーバ構築~

作成日: 2014/05/27

OSSでLinuxサーバ構築

PostgreSQL 9.0でストリーミングレプリケーションとホットスタンバイの設定

トップページOSSでLinuxサーバ構築 > 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

(1) WAL転送プロセスの設定

 postgresql.confファイルをエディタで編集します。 スタンバイ側からのWALの送信要求に応えるプロセスの数を設定します。

-bash-3.2$ cd /data/pgdata1/
-bash-3.2$ vi postgresql.conf
ファイル名:/data/pgdata1/postgresql.conf
※以下、該当箇所のみ変更※
#max_wal_senders = 0          # max number of walsender processes
   ↓変更
max_wal_senders = 2           # max number of walsender processes

(2) ホストベース認証の設定

 スタンバイ側からのレプリケーション要求を許可するための認証設定を行います。 スタンバイ側(IPアドレス/ネットマスクは192.168.0.77/24)からTCP/IP接続で postgresユーザで接続してきた場合は信頼(許可)します。

-bash-3.2$ vi pg_hba.conf
ファイル名:/data/pgdata1/pg_hba.conf
※ファイルの末尾に追加※
host     replication     postgres        192.168.0.77/24         trust

(3) PostgreSQLインスタンスの再起動

 一通り必要な設定が終わったらPostgreSQLインスタンスを再起動します。

-bash-3.2$ pg_ctl restart -w
サーバ停止処理の完了を待っています....完了
サーバは停止しました
サーバの起動完了を待っています....完了
サーバ起動完了

(4) ベースバックアップ前の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$

(5) ベースバックアップの取得

 データベースクラスタのベースバックアップを取得します。 取得には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

(6) ベースバックアップ後の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

(1) アクティブ側で取得したベースバックアップの転送

 アクティブ側で取得したベースバックアップを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

(2) ベースバックアップの展開

 ベースバックアップの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

(3) ホットスタンバイの設定

 ベースバックアップとしてアクティブ側からコピーした postgresql.confファイルをスタンバイ用に編集します。 まず、PostgreSQLインスタンスが接続をリスニングするIPアドレスを スタンバイサーバのIPアドレスに変更します。 また、ホットスタンバイの設定を有効にします。 これによりアクティブ側での変更を反映させている最中も SQLによる参照を許可します。

-bash-3.2$ cd /data/pgdata1/
-bash-3.2$ vi postgresql.conf
ファイル名:/data/pgdata1/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

(4) ホストベース認証の設定

 アクティブ側でレプリケーション要求を許可するための設定を行いましたが、 スタンバイ側では不要ですので該当行を削除します。

-bash-3.2$ vi pg_hba.conf
ファイル名:/data/pgdata1/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 ←削除

(5) アクティブ側からWALを受信するための設定

 レプリケーションの際に、アクティブ側からWALを取得するための設定を行います。

-bash-3.2$ vi recovery.conf
ファイル名:/data/pgdata1/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'

(6) 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$

プロフィール

らのっち

損害保険会社のIT企画部に勤務するSEです。OSSを勉強中です。

<所属>
日本PostgreSQLユーザ会とくしまOSS普及協議会

■■■ 当サイトは Internet Explorer 11 と Mozilla Firefox 43 で動作確認済みです。 ■■■