Linux Install Memo

サーバー管理者によるLinux関連ソフトのインストールメモ

Home » □PostgreSQL9.2のレプリケーションを試してみた

□PostgreSQL9.2のレプリケーションを試してみた

□PostgreSQLのレプリケーションを試してみた

http://lets.postgresql.jp/documents/technical/replication/1
http://www.interdb.jp/techinfo/pg_sr/sr_sync01.html
http://d.hatena.ne.jp/hiroe_orz17/20111113/1321180635

PostgreSQLは9.0から非同期レプリケーション(データ複製とか冗長化とか)
に対応している。9.1からは同期レプリケーションにも対応している。

『レプリケーションだけなら』pgpool-IIとかは要らず、基本的にはマスター
とスレーブ双方でちょこっと設定するだけでOKとなっている。

せっかくなのでコレをCentOSのKVM上に設定して、レプリケーションの実際
をテストしながら試してみる。

マスターサーバーをmaster00として、レプリケーション先サーバーをsub01と
sub02とする。

インストールするパッケージはBASIC SERVERをカスタマイズして、

・WEBサービス
 ・PHPサポート
 ・WEBサーバー
・アプリケーション
 ・EMACS
・サーバー
 ・電子メールサーバー
・システム管理
 ・SNMPサポート
・データベース
 ・PostgreSQLの全て
・開発
 ・その他の開発
 ・開発ツール

をとりあえずインストールする。

・master00(192.168.100.200)

virt-install \
–connect qemu:///system \
–name=master00 \
–ram=4096 \
–file=/vps/images/master00.img \
–file-size=10 \
–vcpus=2 \
–os-type=linux \
–os-variant=virtio26 \
–network bridge=br0 \
–accelerate \
–hvm \
–location http://fwnet.or.jp/package/centos/6/os/x86_64/ \
–graphics vnc,port=5900,listen=0.0.0.0,keymap=ja,password=hogehoge \
–extra-args=’hostname=master00′

mv /etc/libvirt/qemu/master00.xml /vps/conf/
ln -s /vps/conf/master00.xml
/etc/libvirt/qemu/autostart/master00.xml
ln -s /vps/conf/master00.xml /etc/libvirt/qemu/master00.xml
・sub01(192.168.100.201)

virt-install \
–connect qemu:///system \
–name=sub01 \
–ram=4096 \
–file=/vps/images/sub01.img \
–file-size=10 \
–vcpus=2 \
–os-type=linux \
–os-variant=virtio26 \
–network bridge=br0 \
–accelerate \
–hvm \
–location http://fwnet.or.jp/package/centos/6/os/x86_64/ \
–graphics vnc,port=5901,listen=0.0.0.0,keymap=ja,password=hogehoge \
–extra-args=’hostname=sub01′

mv /etc/libvirt/qemu/sub01.xml /vps/conf/
ln -s /vps/conf/sub01.xml /etc/libvirt/qemu/autostart/sub01.xml
ln -s /vps/conf/sub01.xml /etc/libvirt/qemu/sub01.xml
・sub02(192.168.100.202)

virt-install \
–connect qemu:///system \
–name=sub02 \
–ram=4096 \
–file=/vps/images/sub02.img \
–file-size=10 \
–vcpus=2 \
–os-type=linux \
–os-variant=virtio26 \
–network bridge=br0 \
–accelerate \
–hvm \
–location http://fwnet.or.jp/package/centos/6/os/x86_64/ \
–graphics vnc,port=5902,listen=0.0.0.0,keymap=ja,password=hogehoge \
–extra-args=’hostname=sub02′

mv /etc/libvirt/qemu/sub02.xml /vps/conf/
ln -s /vps/conf/sub02.xml /etc/libvirt/qemu/autostart/sub02.xml
ln -s /vps/conf/sub02.xml /etc/libvirt/qemu/sub02.xml
…とインストールしてみたら、PostgreSQLのCentOS6.2でのバージョンは

> Name        : postgresql
> Arch        : x86_64
> Version     : 8.4.11
> Release     : 1.el6_2

と、古いのでレプリケーションテストが出来ない。

なので、別途PostgreSQLのリポジトリから最新版を取って来る。

http://storagecell.blog.fc2.com/blog-entry-2.html
http://d.hatena.ne.jp/ymko/20120422/p2

マスター、レプリケーション先サーバーそれぞれで、まずはインストール
しちゃった古いパッケージグループを削除

yum -y groupremove PostgreSQL*

で、とりあえずのダウンロード用ディレクトリを作って

mkdir /usr/src/package/
cd /usr/src/package/

PostgreSQL9.2とかを取ってこれるリポジトリを落として来てインストール。

wget http://yum.pgrpms.org/9.2/redhat/rhel-6-x86_64/pgdg-centos92-9.2-5.noarch.rpm
rpm -ivh pgdg-centos92-9.2-5.noarch.rpm

yum search postgresql

として、postgresql92シリーズがリストにある事を確認してから、インストール。

yum -y install postgresql92 postgresql92-devel postgresql92-libs postgresql92-server postgresql92-contrib

で、入ったらデータベースの準備とかしましょう。

service postgresql-9.2 initdb
/etc/init.d/postgresql-9.2 start
chkconfig –level 345 postgresql-9.2 on

あとは、実際のレプリケーションテストに入ること。

■同期レプリケーションの設定

マスターサーバーでレプリケーション用ユーザーの追加

su – postgres
createuser -A -D -P -E –replication sub01
createuser -A -D -P -E –replication sub02

として追加する。

続いてレプリケーション用データベースへのアクセス許可を設定

emacs /var/lib/pgsql/9.2/data/pg_hba.conf

> host    replication     sub01            192.168.100.0/24       md5
> host    replication     sub02            192.168.100.0/24       md5

そしたらマスターサーバーのレプリケーション設定をする。
ただし、この段階ではまだレプリケーションはOFFにしておいた方がいいらしい。

emacs /var/lib/pgsql/9.2/data/postgresql.conf

> wal_level = minimal                     # minimal, archive, or hot_standby
>                                         # (change requires restart)
> archive_mode = off              # allows archiving to be done
>                                 # (change requires restart)
> max_wal_senders = 0             # max number of walsender processes
>                                 # (change requires restart)

それと、

> #hot_standby = off                      # “on” allows queries during recovery
>                                         # (change requires restart)

はあとでonにする。

これらのパラメータをいじったらrestartしろと書いてあるのでする。

/etc/init.d/pdns-server restart

そしたらテスト用のデータを入れてバキュームしてきれいにしておく。

su – postgres
/usr/pgsql-9.2/bin/pgbench -p 5432 -i

vacuumdb –all –analyze

ここまで準備が出来たらマスターサーバーのレプリケーションをONにする。
悩みどころはWAL(ログ先行書き込み)をアーカイブするかどうかだけど、
今回はDBサーバーが別々になるのでNFSも面倒だし、ということでしない
ことにする。実際にはデータベースの用途(信頼性その他)で決定すること。
(ちなみにWALアーカイブをすると手間は増えるがすくいようも増す)

emacs /var/lib/pgsql/9.2/data/postgresql.conf

> wal_level = hot_standby                 # minimal, archive, or hot_standby
>                                         # (change requires restart)

> max_wal_senders = 3             # max number of walsender processes
>                                 # (change requires restart)

> wal_keep_segments = 8           # in logfile segments, 16MB each; 0 disables

> synchronous_standby_names = ‘sub01, sub02’      # standby servers that provide sync rep
>                                 # comma-separated list of application_name
>                                 # from standby(s); ‘*’ = all

max_wal_sendersはレプリケーション先サーバーを二機としているので2+1で
3としている。

synchronous_standby_namesには、このあとで設定するレプリケーション先
サーバー名(別にHOSTNAMEと同じでなくてもいいけど)を列記する。

そしたらマスターサーバーのPostgreSQLを再起動。

/etc/init.d/pdns-server restart

■マスターサーバーからレプリケーション先サーバーにレプリケーション

まずは一括コピー。

試しに、本来とは違うディレクトリにバックアップコピーしてみる。

su – postgres

mkdir /tmp/sub01

/usr/pgsql-9.2/bin/pg_basebackup \
  -h 192.168.100.200 -p 5432  -U sub01 -D /tmp/sub01 \
  –xlog=fetch –checkpoint=fast –progress

これで

> 59616/59616 kB (100%), 1/1 tablespace

こんな感じでコピーできたら、本来のデータディレクトリにコピーする。

su – postgres
/usr/pgsql-9.2/bin/pg_basebackup \
  -h 192.168.100.200 -p 5432  -U sub01 -D /var/lib/pgsql/9.2/data/ \
  –xlog=fetch –checkpoint=fast –progress

続いてレプリケーション先サーバーの設定。

emacs /var/lib/pgsql/9.2/data/postgresql.conf

> hot_standby = on                        # “on” allows queries during recovery
>                                         # (change requires restart)

emacs /var/lib/pgsql/9.2/data/recovery.conf

> standby_mode = ‘on’
> primary_conninfo = ‘host=192.168.100.200 port=5432 user=sub01 password=areare application_name=sub01’

のようにして、マスターサーバーへの接続設定と、非同期レプリケーション
の時にはなかった「application_name=sub01」という、自身のサーバー名を
設定する。

設定を追加したら、レプリケーション先サーバーsub01のPostgreSQLを
とりあえず手動で起動。

su – postgres
pg_ctl start -D /var/lib/pgsql/9.2/data/

OKそうなら、改めて

/etc/init.d/postgresql-9.2 restart

として、

tail -f /var/lib/pgsql/9.2/data/pg_log/postgresql-*.log

とでもしてみて(実際には再起動した曜日のファイル名:postgresql-Tue.log)

> LOG:  スタンバイモードに入ります
> LOG:  0/8000020のREDOを開始します
> LOG:  0/9000000 でリカバリー状態の整合が取れました
> LOG:  データベースシステムはリードオンリー接続の受付準備ができました
> LOG:  ストリーミングレプリケーションがプライマリに無事接続できました

という感じになる。

マスターサーバー側のログも見てみると、

> ステートメント:  application_name,state,sync_priority,sync_state FROM pg_stat_replication;
> LOG:  スタンバイの “sub01” には優先度 1 で同期スタンバイが設定されています

と言うようにsub01が繋がったというメッセージが出る。

この時に

psql -x -p 5432 -c “SELECT application_name,state,sync_priority,sync_state FROM pg_stat_replication;”

とすると、

> -[ RECORD 1 ]—-+———-
> application_name | sub01
> state            | streaming
> sync_priority    | 1
> sync_state       | sync

というように確認できる。

さらにsub02もPostgreSQLを再起動すると、

> -[ RECORD 1 ]—-+———-
> application_name | sub01
> state            | streaming
> sync_priority    | 1
> sync_state       | sync
> -[ RECORD 2 ]—-+———-
> application_name | sub02
> state            | streaming
> sync_priority    | 2
> sync_state       | potential

のように増える。

ログにはsub02のメッセージが出てこないのが気になると思うが、

http://www.interdb.jp/techinfo/pg_sr/sr_sync01.html
「PostgreSQL ver9.1の同期レプリケーションはスレーブ1台のみ有効なので
 slave2はslave1が停止するまで”非同期レプリケーション”で稼働する」

ということらしい。

■レプリケーションの確認

マスターサーバーで、以下の二行をコピペする。

/usr/pgsql-9.2/bin/pgbench -p 5432 -T 180
psql -x -p 5432 -c “SELECT * FROM pg_stat_replication”

すると、

> -[ RECORD 1 ]—-+——————————
> pid              | 23391
> usesysid         | 16470
> usename          | sub01
> application_name | walreceiver
> client_addr      | 192.168.100.201
> client_hostname  |
> client_port      | 59310
> backend_start    | 2012-06-19 13:08:56.288866+09
> state            | streaming
> sent_location    | 0/C159CB0
> write_location   | 0/C159CB0
> flush_location   | 0/C159CB0
> replay_location  | 0/C159AA0
> sync_priority    | 0
> sync_state       | async

となるが、この時「sent_location」と「replay_location」の差が同期の差。
少ししてからまた

psql -x -p 5432 -c “SELECT * FROM pg_stat_replication”

とすると、

> -[ RECORD 1 ]—-+——————————
> pid              | 23391
> usesysid         | 16470
> usename          | sub01
> application_name | walreceiver
> client_addr      | 192.168.100.201
> client_hostname  |
> client_port      | 59310
> backend_start    | 2012-06-19 13:08:56.288866+09
> state            | streaming
> sent_location    | 0/C15E6F0
> write_location   | 0/C15E6F0
> flush_location   | 0/C15E6F0
> replay_location  | 0/C15E6F0
> sync_priority    | 0
> sync_state       | async

というように、差がなくなって同期も取れたことが判る。

またレプリケーション先サーバーで

psql -p 5432 -c “SELECT pg_last_xact_replay_timestamp()”

とすると、いつまでのデータをマスターサーバーからレプリケーションしたか
という日時を見ることが出来る。

>  pg_last_xact_replay_timestamp
> ——————————-
>  2012-06-19 13:16:23.2158+09

レプリケーション処理が発生しないと、コレは空っぽのまま。

■トラブル発生時の対応方法

参考URLにも書いてあるが、PostgreSQLはそれ自体がトラブって落ちたとして
も、何か便利に自動的に切り替わってサービスが継続できると言うわけでは
ない。

Pacemakerやpgpool-IIの管理機能などを組み合わせることで、上位アプリが
(比較的)意識しなくてもデータベースが切り替わるように仕組みを作らないと
いけない。

これはぶっちゃけ、システム構築をする自分たちでその経験を活かしつつ、
自分たちでサービスを継続する仕組みそのものを作ったほうがいいと未だに
思う。上記のようなツールを使っても、トラブルがそれらの想定を超えた場合
には、何も出来なくなるようなことは避けたほうがよい。

どうせトラぶった時のデータの整合性を確認しなければならないのだから、
いかに迅速にサービスを復旧できるかだろう。

レプリケーションのメリットは、このいわばほぼリアルタイムバックアップ
ができるということと、参照に限った負荷分散と言うことになるんだろうか
なー。

とにかく一度はやってみると、レプリケーションと言うのは何処まで、どの
ようにやってくれるのか判るので、何処から自分たちでフォローしなければ
いけないかも見えてくるんじゃないかと思う。

 

Name of author

Name: admin

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です