ストリーミング・レプリケーションの紹介

2011年10月20日(木)
那賀 樹一郎(なか きいちろう)

非同期レプリケーションを試してみる

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

図2:非同期レプリケーションの構成(クリックで拡大)

プライマリノード用のデータベースクラスタ(PostgreSQL のデータ格納ディレクトリ)を作成します。PostgreSQL では、root 権限でデータベースサーバを作成、稼働させることはできませんので、以降の作業は postgres ユーザとして行います。initdb コマンドでは、データベースユーザ名を明示しなければ OS ユーザと同名のスーパーユーザが作られますので、ここでは "postgres" がスーパーユーザ名となります。デフォルトで、MD5 でのパスワード認証が有効になるようにしておきます。パスワードは、ここでは "postgres" とします。

[root@node1 ~]# su - postgres
-bash-4.1$ export PATH=/usr/pgsql-9.1/bin/:$PATH
-bash-4.1$ initdb -D ~/pgdata-prim/ --encoding=UTF-8 --no-locale --pwprompt --auth=md5
(中略)
新しいスーパーユーザのパスワードを入力してください: postgres
再入力してください: postgres
(中略)
成功しました。以下を使用してデータベースサーバを起動することができます。

    postmaster -D /var/lib/pgsql/pgdata-prim
または
    pg_ctl -D /var/lib/pgsql/pgdata-prim -l logfile start
    
-bash-4.1$ 

指示の通り、データベースを起動させます。

-bash-4.1$ pg_ctl -D ~/pgdata-prim/ start
サーバは起動中です。
-bash-4.1$

パスワード入力なしでデータベースへ接続ができるように、~postgres/.pgpass ファイルを設定しておきます。

-bash-4.1$ echo localhost:5432:postgres:postgres:postgres > ~/.pgpass
-bash-4.1$ echo localhost:5433:postgres:postgres:postgres >> ~/.pgpass
-bash-4.1$ chmod 600 ~/.pgpass
-bash-4.1$

次に、ストリーミング・レプリケーションのプライマリとして動作するように設定をします。

PostgreSQL 9.0 までは、レプリケーション接続に管理者権限が必要だったのですが、9.1 から、より権限を限定した、レプリケーション専用の権限が追加されました。レプリケーション接続専用のロール(ここでは "reprole")を作成してレプリケーション権限とログイン権限を付与し、パスワード(ここでは "reppass")を設定します。

-bash-4.1$ psql
psql (9.1.1)
"help" でヘルプを表示します.

postgres=# CREATE ROLE reprole REPLICATION PASSWORD 'reppass';
CREATE ROLE
postgres=# ALTER ROLE reprole LOGIN;
ALTER ROLE
postgres=# \quit
-bash-4.1$

次に、~postgres/pgdata-prim/postgresql.conf の以下の項目を修正します。

## 全ての NIC で (0.0.0.0 上で) 接続ポートを開くようにします。
listen_addresses = '*'

## 今回は同一ホスト上にプライマリとスタンバイのノードを起動させますので、
## 接続ポートが重複しないようにします (プライマリ: 5432, スタンバイ: 5433)。
port = 5432

## ホット・スタンバイに必要な付加情報を WAL レコードに書き出すように指示
## します。
wal_level = hot_standby

## WAL 送出プロセスの最大数を設定します。
max_wal_senders = 10

## WAL 要求に備えて、再利用せずに保持する WAL セグメントファイルの個数を
## 指定します。1 ファイル 16MB ありますので、容量に注意してください。
wal_keep_segments = 1000

## 現時点では同期ノードはまだ設定しませんので、空にします。
synchronous_standby_names = ''

## ホット・スタンバイを有効にします。このパラメータはプライマリ側では
## 意味を持ちませんが、後でスタンバイへコピーしてそのまま使うので、
## ここで有効にしておきます
hot_standby = on

レプリケーションの設定に関する詳細については、右記もご参照ください / 「レプリケーション - PostgreSQL 文書」。

次に、スタンバイからの接続を許可するよう ~postgres/pgdata-prim/pg_hba.conf ファイル(host based authentication ファイル)を編集します。下記の行を追加し、ローカルホストからの、レプリケーションのための接続を許可するようにします。

host  replication  reprole  127.0.0.1/32  md5

以上の設定を反映させるために、再起動をします。

-bash-4.1$ pg_ctl -D ~/pgdata-prim/
restart サーバ停止処理の完了を待っています....完了
サーバは停止しました
サーバは起動中です。
-bash-4.1$

次にスタンバイノードを作成します。pg_basebackup コマンド (詳細は次回以降で説明します)を用いて、稼働中のプライマリのスナップショットコピーをとります。

-bash-4.1$ pg_basebackup -x -h localhost -p 5432 -U reprole -D ~/pgdata-stby/
パスワード: reppass
-bash-4.1$

~postgres/pgdata-stby/postgresql.conf を修正します。

## 今回は同一ホスト上にプライマリとスタンバイのノードを起動させますので、 
## 接続ポートが重複しないようにします (プライマリ: 5432, スタンバイ: 5433)。 
port = 5433

スタンバイ状態のリカバリモードで起動するよう、~postgres/pgdata-stby/recovery.conf を作成します。このファイルはその名の通り、本来は障害後のリカバリの詳細を設定するためのファイルであり、デフォルトの挙動では、リカバリが終了すると通常モードで起動してしまいます。standby_mode パラメータに "on" を指定することで、スタンバイノードはスタンバイモードのまま、プライマリへの変更を継続的に受信・反映するようになります。その際の接続情報は primary_conninfo パラメータに記述します。

standby_mode = 'on'
primary_conninfo = 'host=localhost port=5432 user=reprole password=reppass application_name=stby'

以上でスタンバイの設定も終わりです。スタンバイ側のサービスを起動します。

-bash-4.1$ pg_ctl -D ~/pgdata-stby/ start
サーバは起動中です。
-bash-4.1$

ホット・スタンバイが有効であることを確認してみます。

-bash-4.1$ psql -p 5432 -c "CREATE TABLE members(id integer, name text)"
CREATE TABLE
-bash-4.1$ psql -p 5432 -c "INSERT INTO members VALUES(123, 'Foo')"
INSERT 0 1
-bash-4.1$ psql -p 5432 -c "SELECT * FROM members" # これはプライマリ側
 id  | name
-----+------
 123 | Foo
(1 行)

-bash-4.1$ psql -p 5433 -c "SELECT * FROM members" # こちらはスタンバイ側
 id  | name
-----+------
 123 | Foo
(1 行)

-bash-4.1$

ホット・スタンバイノードへは書き込みができません。

-bash-4.1$ psql -p 5433 -c "INSERT INTO members VALUES(456, 'Bar')"
ERROR:  cannot execute INSERT in a read-only transaction
-bash-4.1$

以下のようにしてホット・スタンバイをプライマリへ昇格させると、レプリケーションが停止し、書き込みクエリを受け入れるようになります

注意!: 一度昇格を行うと、元のプライマリ→セカンダリでのレプリケーション状態に戻すには、再度、上記の一連の構成の手続きが必要になります。次回は、昇格以前の状態からの続きとして進行します。こちらも、詳細は次回以降で説明します。

-bash-4.1$ pg_ctl -D ~/pgdata-stby/ promote
サーバを昇進中です。
-bash-4.1$ psql -p 5433 -c "INSERT INTO members VALUES(789, 'Buzz')"
INSERT 0 1
-bash-4.1$

次回は、レプリケーションの状態を監視するためのビューや関数、関連するツールを紹介します。また、今回作成した非同期構成を、同期構成に変更して行きます。

【関連リンク】

<サイト最終アクセス:2010.10>

著者
那賀 樹一郎(なか きいちろう)

サイオステクノロジー株式会社にて、PostgreSQL/Postgres Plus の製品担当として、サポートサービス、コンサルティング、トレーニング等を行う。Linux ディストリビューションベンダーで培った、OSS プロダクトのソースコードレベルでのソフトウェア解析技術を生かして業務にあたる。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています