PostgreSQLのレプリケーション機能をつかってみた
皆様、ご無沙汰しております。笹亀@イネ花粉に苦しんでます。
昨日(7/10)、最近愛用してい るPhpStormを開発しているJetBrainsのエバンジェリストとCEOの方が来日されて、講演をされるとのことで、参加をしてきました。
http://www.zusaar.com/event/844003
内容もよかったのですが、エバンジェリストの方がとてもユニークな方だったのが印象的でした。
さて、本日は少し前から興味を持っていたのですが、中々試す機会がなかった内容です。
今回はPostgreSQLのレプリケーションの設定を解説しながらご紹介をしていきたいと思います。
PostgreSQLのレプリケーションについて
まずは、マスターとスレーブにするサーバへPostgreSQLをインストールしておきます。
インストールするバージョンは必ず9.2以上でインストールしてください。また、インストールはそれぞれの環境でご準備くださいませ。インストール方法については割愛します。(googleさんにお聞きください(笑))
PostgreSQLのレプリケーションだけではなく、マスター側で更新処理(登録・更新・削除など)があった場合にスレーブへ更新情報をやり取りする必要があります。PostgreSQLではその更新のやり取りをWAL(Write Ahead Logging)にて行われます。WALはテーブルに書き込みを行う前に変更情報を記録しているログです。ログにはアンドゥとリドゥ用の情報が含まれていることから、DBMSがクラッシュしたときなどには、クラッシュ直前までリカバリを行うこともできます。
PostgreSQLのレプリケーションでは、WALの同期をさせるタイミングについて、以下の4つの設定することができます。
■同期
マスターと1台のスレーブのディスクへのWALを書き込み後にユーザにレスポンスする
■メモリ同期
マスタのディスクと1台のスレーブのメモリへのWALを書き込み後にユーザにレスポンスする
■スレーブ非同期
マスターのディスクへのWALを書き込み後にユーザにレスポンスする(スレーブへの書き込みは確認しない)
■完全非同期
マスター・スレーブともにWAL書き込みを待たずにユーザにレスポンスする(WALはマスターのメモリ上のみ)
スレーブ非同期がMySQLにて弊社でもよく使っているレプリケーションの同期設定です。
今回の設定も「スレーブ非同期」にて設定をしていきます。
レプリケーションの設定(マスター側)
それでは実際にマスター側のPostgreSQLの設定をしていきます!
1.レプリケーションをするためのPostgreのユーザを作成する
psqlコマンドでログインをして、下記のコマンドでユーザをつくります。
CREATE USER repl_user REPLICATION PASSWORD 'xxx';
2.postgres.confにマスターの設定を追加する
postgresql.confはPostgreSQLデータフォルダ内にあります。
エディターでファイルを開いて更新します。
wal_level = hot_standby #WALの出力内容をレプリケーションに対応
synchronous_commit = local #同期方式の設定
#synchronous_commitで指定できるレプリケーションの同期方式は下記の通りです。
# 同期:on
# メモリ同期:remote_write
# スレーブ非同期:local
# 完全非同期:off
max_wal_senders = 2 #スレーブの数 + 1
synchronous_standby_names = 'slave1_test'
#同期/メモリ同 期レプリケーションで同期スレーブとして動作可能なサーバ
#これを設定しないとスレーブ非同期レプリケーションで動作する。(今回はスレーブ非同期ですが、念の為に設定しておく。)
#スレーブのrecovery.confに設定するprimary_conninfoのapplication_name=と同一にする
3.pg_hba.confにマスターの設定を追加する
pg_hba.confはPostgreSQLデータフォルダ内にあります。
エディターでファイルを開いて更新します。
host replication repl_user x.x.x.x/xx password
#スレーブのrecovery.confに設定するprimary_conninfoのapplication_name=と同一にする
4.マスター側のPostgreSQLを再起動
コマンドは省略
5.マスター側のデータをスレーブで使用するためにバックアップする
pg_basebackupでスレーブサーバ用のデータを作成する
例)
/opt/local/lib/postgresql92/bin/pg_basebackup -h localhost -p 5432 -D /opt/local/var/db/postgresql92/data_slavedb/ --xlog --progress --verbose
レプリケーションの設定(スレーブ側)
次にスレーブ側のPostgreSQLの設定をしていきます!
1.マスター側で作成したバックアップをスレーブのデータフォルダへコピーする
データフォルダーごと上書きして更新をする。
2.postgres.confにスレーブの設定を追加する
postgresql.confはPostgreSQLデータフォルダ内にあります。
エディターでファイルを開いて更新します。
hot_standby = on
3.recovery.confにスレーブの設定を追加する
サンプルからコピーしてrecovery.confとファイル名をします。Macの場合は「/opt/local/share/postgresql92/recovery.conf.sample」にありました。
standby_mode = 'on'
primary_conninfo = 'host=master_hostname port=5432 user=repl_user password=xxx application_name=slave_hostname' #マスターへの接続情報
#application_nameは同 期/メモリ同期の場合にのみ必要
#マスターのpostgres.confに設定したsynchronous_standby_namesと同一にする
4.スレーブを起動させる
起動しようとしたら【postmaster.opts を読み取ることに失敗しました】とエラーが出た場合は、
postmaster.optsで実行している-dで指定しているデータフォルダを正しい箇所に修正ください。
↓私の環境の場合となります
/opt/local/lib/postgresql92/bin/postgres "-D" "/opt/local/var/db/postgresql92/data_slavedb"
また余談ですが、Macの場合であったのですが、ローカル上で2つのデータフォルダを用意して、それぞれを別ポートで複数立ち上げる場合に、
Macはカーネルで取得できるshared memoryの量がかなり低く設定されているので、shared bufferを確保できずにエラーになることがあります。
下記のコマンドを実行すると起動できるようになります。
sudo sysctl -w kern.sysv.shmmax=1073741824
sudo sysctl -w kern.sysv.shmall=1073741824
5.マスターとスレーブ間で正しく同期がされているかを確認する
■マスター側で実行
psql -c "select application_name, state, sync_priority, sync_state from pg_stat_replication;"
マスター側にデータベースとテーブルとデータ登録をしてスレーブ側に同期されているかを確認します。
psql -p 5432
psql -p 5432 -c "create database sasa_test;"
psql -p 5432 sasa_test
# CREATE TABLE sasa_table (id int primary key,test_text text);
# insert into sasa_table values('1', 'sasa_test');
スレーブ側で反映されているか確認する
psql -p 5433 -l
※[データベースリスト]参照
psql -p 5433 sasa_test
# select * from sasa_table;
※[データ情報確 認]参照
これでPostgreSQLでも同期がされていることが確認できました。今まではPostgreSQLではpg_poolなどを利用してプーリングをさせることが一般的でした。MySQLを使用していた理由としてレプリケーション機能は大きいものでした。これでPostgreSQLでも同様のことができることが確認できましたので、新しいシステムでも使用する頻度もおおくなりそうです。
今回のブログでは「http://codezine.jp/article/detail/7109」の情報を参考に記載させていただきました。この場をお借り致しましてお礼申し上げます。ありがとうございました。