非同期レプリケーションを試してみる
続いて、非同期でのレプリケーションを設定します。構成は以下のようになります。

|
図2:非同期レプリケーションの構成(クリックで拡大) |
プライマリノード用のデータベースクラスタ(PostgreSQL のデータ格納ディレクトリ)を作成します。PostgreSQL では、root 権限でデータベースサーバを作成、稼働させることはできませんので、以降の作業は postgres ユーザとして行います。initdb コマンドでは、データベースユーザ名を明示しなければ OS ユーザと同名のスーパーユーザが作られますので、ここでは "postgres" がスーパーユーザ名となります。デフォルトで、MD5 でのパスワード認証が有効になるようにしておきます。パスワードは、ここでは "postgres" とします。
01 | [root@node1 ~]# su - postgres |
02 | -bash-4.1$ export PATH=/usr/pgsql-9.1/bin/:$PATH |
03 | -bash-4.1$ initdb -D ~/pgdata-prim/ --encoding=UTF-8 --no-locale --pwprompt --auth=md5 |
05 | 新しいスーパーユーザのパスワードを入力してください: postgres |
08 | 成功しました。以下を使用してデータベースサーバを起動することができます。 |
10 | postmaster -D /var/lib/pgsql/pgdata-prim |
12 | pg_ctl -D /var/lib/pgsql/pgdata-prim -l logfile start |
指示の通り、データベースを起動させます。
1 | -bash-4.1$ pg_ctl -D ~/pgdata-prim/ start |
パスワード入力なしでデータベースへ接続ができるように、~postgres/.pgpass ファイルを設定しておきます。
1 | -bash-4.1$ echo localhost:5432:postgres:postgres:postgres > ~/.pgpass |
2 | -bash-4.1$ echo localhost:5433:postgres:postgres:postgres >> ~/.pgpass |
3 | -bash-4.1$ chmod 600 ~/.pgpass |
次に、ストリーミング・レプリケーションのプライマリとして動作するように設定をします。
PostgreSQL 9.0 までは、レプリケーション接続に管理者権限が必要だったのですが、9.1 から、より権限を限定した、レプリケーション専用の権限が追加されました。レプリケーション接続専用のロール(ここでは "reprole")を作成してレプリケーション権限とログイン権限を付与し、パスワード(ここでは "reppass")を設定します。
05 | postgres=# CREATE ROLE reprole REPLICATION PASSWORD 'reppass'; |
07 | postgres=# ALTER ROLE reprole LOGIN; |
次に、~postgres/pgdata-prim/postgresql.conf の以下の項目を修正します。
01 | ## 全ての NIC で (0.0.0.0 上で) 接続ポートを開くようにします。 |
04 | ## 今回は同一ホスト上にプライマリとスタンバイのノードを起動させますので、 |
05 | ## 接続ポートが重複しないようにします (プライマリ: 5432, スタンバイ: 5433)。 |
08 | ## ホット・スタンバイに必要な付加情報を WAL レコードに書き出すように指示 |
10 | wal_level = hot_standby |
12 | ## WAL 送出プロセスの最大数を設定します。 |
15 | ## WAL 要求に備えて、再利用せずに保持する WAL セグメントファイルの個数を |
16 | ## 指定します。1 ファイル 16MB ありますので、容量に注意してください。 |
17 | wal_keep_segments = 1000 |
19 | ## 現時点では同期ノードはまだ設定しませんので、空にします。 |
20 | synchronous_standby_names = '' |
22 | ## ホット・スタンバイを有効にします。このパラメータはプライマリ側では |
23 | ## 意味を持ちませんが、後でスタンバイへコピーしてそのまま使うので、 |
レプリケーションの設定に関する詳細については、右記もご参照ください / 「レプリケーション - PostgreSQL 文書」。
次に、スタンバイからの接続を許可するよう ~postgres/pgdata-prim/pg_hba.conf ファイル(host based authentication ファイル)を編集します。下記の行を追加し、ローカルホストからの、レプリケーションのための接続を許可するようにします。
1 | host replication reprole 127.0.0.1/32 md5 |
以上の設定を反映させるために、再起動をします。
1 | -bash-4.1$ pg_ctl -D ~/pgdata-prim/ |
2 | restart サーバ停止処理の完了を待っています....完了 |
次にスタンバイノードを作成します。pg_basebackup コマンド (詳細は次回以降で説明します)を用いて、稼働中のプライマリのスナップショットコピーをとります。
1 | -bash-4.1$ pg_basebackup -x -h localhost -p 5432 -U reprole -D ~/pgdata-stby/ |
~postgres/pgdata-stby/postgresql.conf を修正します。
1 | ## 今回は同一ホスト上にプライマリとスタンバイのノードを起動させますので、 |
2 | ## 接続ポートが重複しないようにします (プライマリ: 5432, スタンバイ: 5433)。 |
スタンバイ状態のリカバリモードで起動するよう、~postgres/pgdata-stby/recovery.conf を作成します。このファイルはその名の通り、本来は障害後のリカバリの詳細を設定するためのファイルであり、デフォルトの挙動では、リカバリが終了すると通常モードで起動してしまいます。standby_mode パラメータに "on" を指定することで、スタンバイノードはスタンバイモードのまま、プライマリへの変更を継続的に受信・反映するようになります。その際の接続情報は primary_conninfo パラメータに記述します。
2 | primary_conninfo = 'host=localhost port=5432 user=reprole password=reppass application_name=stby' |
以上でスタンバイの設定も終わりです。スタンバイ側のサービスを起動します。
1 | -bash-4.1$ pg_ctl -D ~/pgdata-stby/ start |
ホット・スタンバイが有効であることを確認してみます。
01 | -bash-4.1$ psql -p 5432 -c "CREATE TABLE members(id integer, name text)" |
03 | -bash-4.1$ psql -p 5432 -c "INSERT INTO members VALUES(123, 'Foo')" |
05 | -bash-4.1$ psql -p 5432 -c "SELECT * FROM members" # これはプライマリ側 |
11 | -bash-4.1$ psql -p 5433 -c "SELECT * FROM members" # こちらはスタンバイ側 |
ホット・スタンバイノードへは書き込みができません。
1 | -bash-4.1$ psql -p 5433 -c "INSERT INTO members VALUES(456, 'Bar')" |
2 | ERROR: cannot execute INSERT in a read-only transaction |
以下のようにしてホット・スタンバイをプライマリへ昇格させると、レプリケーションが停止し、書き込みクエリを受け入れるようになります
注意!: 一度昇格を行うと、元のプライマリ→セカンダリでのレプリケーション状態に戻すには、再度、上記の一連の構成の手続きが必要になります。次回は、昇格以前の状態からの続きとして進行します。こちらも、詳細は次回以降で説明します。
1 | -bash-4.1$ pg_ctl -D ~/pgdata-stby/ promote |
3 | -bash-4.1$ psql -p 5433 -c "INSERT INTO members VALUES(789, 'Buzz')" |
次回は、レプリケーションの状態を監視するためのビューや関数、関連するツールを紹介します。また、今回作成した非同期構成を、同期構成に変更して行きます。
【関連リンク】
<サイト最終アクセス:2010.10>