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

作成日: 2016/07/25

OSSでLinuxサーバ構築

PostgreSQL 9.4.8のストリーミングレプリケーション構築後の動作確認

トップページOSSでLinuxサーバ構築 > PostgreSQL 9.4.8のストリーミングレプリケーション構築後の動作確認
このエントリーをはてなブックマークに追加

概要

 PostgreSQLのサーバを2台準備し、ストリーミングレプリケーションを構成します。 2台のうち1台目をマスタサーバとして、通常通りデータの参照、更新を行えるようにします。 2台目をスタンバイサーバとして、マスタサーバでのデータ更新を非同期で取り込むようにします。 なお、スタンバイサーバはホットスタンバイとして構成することで、更新(insert文、updatet文等)はできませんが、参照(select文)のみ行えるようにします。

 運用形態としては、マスタサーバで本番運用し、マスタサーバが障害時にスタンバイサーバをマスタに昇格させます。 ただし、ストリーミングレプリケーションの機能だけでスタンバイか自動でマスタに昇格させることはできません。 別途クラスタウェア等を利用してマスタサーバの障害検知、スタンバイのマスタへの昇格を組み込む必要があります。

 今回の手順ではストリーミングレプリケーションの構成をとるところまでとし、 クラスタウェアとの連携は行わないものとします。

 マスタサーバ、スタンバイサーバの構築が終わったら、実際にマスタサーバでテーブルの作成やデータの挿入などを行い、 レプリケーションが正常に動作していることを確認します。

構成

想定環境

PostgreSQL 9.4.8のストリーミングレプリケーション構成

サーバ構成

OSバージョン

CentOS 7.2.1511 x86_64

パッケージ一覧

  • postgresql94-9.4.8-1PGDG.rhel7.x86_64.rpm
  • postgresql94-libs-9.4.8-1PGDG.rhel7.x86_64.rpm
  • postgresql94-server-9.4.8-1PGDG.rhel7.x86_64.rpm

サーバ構築

マスタサーバでの確認

(1) ストリーミングレプリケーションの状態確認

 ストリーミングレプリケーションの状態を確認します。 state が streaming と表示されていれば、マスタサーバでの更新がスタンバイサーバへ同期されている状態を意味します。

-bash-4.2$ psql -x -c "select * from pg_stat_replication;"
-[ RECORD 1 ]----+------------------------------
pid              | 2937
usesysid         | 16384
usename          | pgrepl01
application_name | walreceiver
client_addr      | 192.168.0.77
client_hostname  |
client_port      | 49486
backend_start    | 2016-07-23 19:20:55.114266+09
backend_xmin     |
state            | streaming ←スタンバイサーバと同期が開始されている状態
sent_location    | 0/7000350
write_location   | 0/7000350
flush_location   | 0/7000318
replay_location  | 0/7000318
sync_priority    | 0
sync_state       | async

-bash-4.2$

(2) データベースユーザの作成

 データベースが同期されることを確認されるために、 データベースの所有者となるユーザ pguser01 を作成します。 なお、このユーザには管理者権限、データベースの作成権限、ロールの作成権限は与えず、ログイン権限のみ付与します。

-bash-4.2$ createuser -P -S -D -R -l pguser01
新しいロールのためのパスワード: ←パスワードを入力(表示されません)
もう一度入力してください: ←上と同じパスワードを入力(表示されません)
-bash-4.2$ psql -c "\du"
                                         ロール一覧
 ロール名 |                                 属性                                 | メンバー
----------+----------------------------------------------------------------------+----------
 pgrepl01 | レプリケーション                                                     | {}
 pguser01 |                                                                      | {} ←作成された
 postgres | スーパーユーザ, ロールを作成できる, DBを作成できる, レプリケーション | {}

-bash-4.2$

(3) データベースの作成

 同期確認のためのデータベース testdb01 を作成します。 データベースの所有者は pguser01 とします。

-bash-4.2$ createdb -O pguser01 testdb01
-bash-4.2$ psql -l
                                        データベース一覧
   名前    |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) |      アクセス権
-----------+----------+------------------+----------+-------------------+-----------------------
 postgres  | postgres | UTF8             | C        | C                 |
 template0 | postgres | UTF8             | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
 template1 | postgres | UTF8             | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
 testdb01  | pguser01 | UTF8             | C        | C                 | ←作成された
(4 行)

-bash-4.2$

(4) テーブルの作成とデータの挿入

 作成したデータベース testdb01 に pguser01 ユーザで接続し、 テーブル addressbook を作成してデータを2件挿入します。

-bash-4.2$ psql -U pguser01 testdb01
ユーザ pguser01 のパスワード: ←pguser01のパスワードを入力(表示されません)
psql (9.4.8)
"help" でヘルプを表示します.

testdb01=> \dt
リレーションがありません。 ←この時点ではまだ存在しません
testdb01=> create table addressbook ( ←テーブルの作成
testdb01(> id integer,
testdb01(> name varchar(20),
testdb01(> address varchar(20),
testdb01(> telephone varchar(13),
testdb01(> primary key (id)
testdb01(> );
CREATE TABLE
testdb01=> \dt
              リレーションの一覧
 スキーマ |    名前     |    型    |  所有者
----------+-------------+----------+----------
 public   | addressbook | テーブル | pguser01 ←テーブルが作成された
(1 行)

testdb01=> insert into addressbook ←1件目のデータ挿入
testdb01-> (id, name, address, telephone)
testdb01-> values
testdb01-> (1, '山田太郎', '東京', '03-1234-5678');
INSERT 0 1
testdb01=> insert into addressbook ←2件目のデータ挿入
testdb01-> (id, name, address, telephone)
testdb01-> values
testdb01-> (2, '田中花子', '大阪', '050-9876-5432');
INSERT 0 1
testdb01=> select * from addressbook; ←挿入したデータの確認
 id |   name   | address |   telephone
----+----------+---------+---------------
  1 | 山田太郎 | 東京    | 03-1234-5678
  2 | 田中花子 | 大阪    | 050-9876-5432
(2 行)

testdb01-> \q
-bash-4.2$

(5) ストリーミングレプリケーションの状態を再確認

 データベースユーザとデータベース、テーブルの作成、テーブルへのデータの挿入後も スタンバイサーバと同期が継続していることを確認します。

-bash-4.2$ psql -x -c "select * from pg_stat_replication;"
-[ RECORD 1 ]----+------------------------------
pid              | 2937
usesysid         | 16384
usename          | pgrepl01
application_name | walreceiver
client_addr      | 192.168.0.77
client_hostname  |
client_port      | 49486
backend_start    | 2016-07-23 19:20:55.114266+09
backend_xmin     |
state            | streaming ←スタンバイサーバと同期状態が継続している
sent_location    | 0/70180D8
write_location   | 0/70180D8
flush_location   | 0/70180D8
replay_location  | 0/70180D8
sync_priority    | 0
sync_state       | async

-bash-4.2$

スタンバイサーバでの確認

(1) データベースユーザとデータベースが同期されていることを確認

 マスタサーバで作成したデータベースユーザ pguser01 とデータベース testdb01 が スタンバイサーバへ同期され、参照できることを確認します。

-bash-4.2$ psql -c "\du"
                                         ロール一覧
 ロール名 |                                 属性                                 | メンバー
----------+----------------------------------------------------------------------+----------
 pgrepl01 | レプリケーション                                                     | {}
 pguser01 |                                                                      | {} ←データベースユーザが同期されている
 postgres | スーパーユーザ, ロールを作成できる, DBを作成できる, レプリケーション | {}

-bash-4.2$ psql -l
                                        データベース一覧
   名前    |  所有者  | エンコーディング | 照合順序 | Ctype(変換演算子) |      アクセス権
-----------+----------+------------------+----------+-------------------+-----------------------
 postgres  | postgres | UTF8             | C        | C                 |
 template0 | postgres | UTF8             | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
 template1 | postgres | UTF8             | C        | C                 | =c/postgres          +
           |          |                  |          |                   | postgres=CTc/postgres
 testdb01  | pguser01 | UTF8             | C        | C                 | ←データベースが同期されている
(4 行)

-bash-4.2$

(2) データが同期されていることと参照のみ可能であることを確認

 マスタサーバで作成したテーブルとテーブルに挿入したデータをスタンバイサーバでも参照できることを確認します。 PostgreSQLのホットスタンバイでは参照のみ可能であるため、一応更新(update文)を実行して失敗することも確認します。

-bash-4.2$ psql -U pguser01 testdb01
ユーザ pguser01 のパスワード: ←pguser01のパスワードを入力(表示されません)
psql (9.4.8)
"help" でヘルプを表示します.

testdb01=> \dt;
              リレーションの一覧
 スキーマ |    名前     |    型    |  所有者
----------+-------------+----------+----------
 public   | addressbook | テーブル | pguser01 ←テーブルが同期されている
(1 行)

testdb01=> select * from addressbook; ←データの参照は成功する
 id |   name   | address |   telephone
----+----------+---------+---------------
  1 | 山田太郎 | 東京    | 03-1234-5678
  2 | 田中花子 | 大阪    | 050-9876-5432
(2 行)

testdb01=> update addressbook set address = '福岡' where id = 2; ←データの更新は失敗する
ERROR:  cannot execute UPDATE in a read-only transaction
testdb01=> \q
-bash-4.2$

プロフィール

らのっち

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

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

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