Slony-Iのデータレプリケーション設定

Slony-Iのデータレプリケーション設定

PostgreSQLのレプリケーション設定のひとつ
『Slony-I』の設定手順です。
http://www.slony.info/



サーバー構成

以下のように想定します。

OS IPアドレス DB名 PostgreSQL Slony-Iバージョン
DBマスターサーバー CentOS 5.4 64bit 10.0.0.1 master PostgreSQL 8.4.5 Slony-I 2.0.6
DBスレーブサーバー CentOS 5.4 64bit 10.0.0.2 slave PostgreSQL 9.0.3 Slony-I 2.0.6


テーブル

以下のテーブルのレプリケーションを行います。

テーブル名
table1
table2
table3


マスターサーバー下準備

まず、「slonik」コマンド経由でマスタデータベースの初期設定を行います。
ファイル名を「master.sh」としたスクリプトファイルを準備します。

#!/bin/sh
CLUSTERNAME=slony_test ←適当な名前をつける
DB1=master ←マスタデータベースの名前
DB2=slave ←スレーブデータベースの名前
HOST1=10.0.0.1 ←マスタのホストアドレス
HOST2=10.0.0.2 ←スレーブのホストアドレス
RUSER=postgres
slonik <<_EOF_
cluster name = $CLUSTERNAME;
node 1 admin conninfo = 'dbname=$DB1 host=$HOST1 user=$RUSER';
node 2 admin conninfo = 'dbname=$DB2 host=$HOST2 user=$RUSER';
init cluster (id=1, comment = 'Master');
create set (id=1, origin=1, comment='All tables');
set add table (set id=1, origin=1, id=1, fully qualified name = 'public.table1',comment='table1');
set add table (set id=1, origin=1, id=2, fully qualified name = 'public.table2',comment='table2');
set add table (set id=1, origin=1, id=3, fully qualified name = 'public.table3',comment='table3');
store node (id=2, comment = 'Slave', event node = 1);
store path (server = 1, client = 2, conninfo='dbname=$DB1 host=$HOST1 user=$RUSER');
store path (server = 2, client = 1, conninfo='dbname=$DB2 host=$HOST2 user=$RUSER');
store listen (origin=1, provider = 1, receiver =2);
store listen (origin=2, provider = 2, receiver =1);
_EOF_

このスクリプトによって、マスタデータベースには通常のpublicとは別の名前空間(スキーマ)が定義され、レプリケーションに必要なテーブルや関数が用意されます。


※注意
Slony-Iのバージョン2を利用する場合に注意が必要なのが、
マスター側のスクリプトでは

store node (id=2, comment = 'Slave');

store node (id=2, comment = 'Slave', event node = 1);

へ変更しないと動作しない。バージョン2からの変更のようです。
http://d.hatena.ne.jp/aaabbb_200904/20090623/1245711019


実行権限を付けておきます。

[root@master ~]# chmod +x master.sh


マスターサーバーslonyログ出力設定

slonyのログ設定を行います。
以下のファイルを編集します。(変更部分と特記事項のみ抜粋)

/etc/slon.conf

# Debug log level (higher value ==> more output).  Range: [0,4], default 4
#log_level=4 #ログの出力はとりあえず全て出力したいのでデフォルトのままの4にしておく。


# If this parameter is 1, messages go both to syslog and the standard 
# output. A value of 2 sends output only to syslog (some messages will 
# still go to the standard output/error).  The default is 0, which means 
# syslog is off.  
# Range:  [0-2], default: 0
#syslog=0
syslog=2 #ログをsyslogにのみ出力するので2へ変更


# Sets the syslog "facility" to be used when syslog enabled.  Valid 
# values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
#syslog_facility=LOCAL0
syslog_facility=LOCAL0 #syslogのログをLOCAL0へ出力


# Sets the program name used to identify slon messages in syslog.
#syslog_ident=slon
syslog_ident=slon_master #masterのログと分かるように変更


syslogのログ出力設定を行います。

/etc/syslog.conf
syslog設定ファイルへ以下を追記します。

# slony log
local0.*					/var/log/slon_master.log

※「local0.*」の部分は/etc/slon.confのロギングファシリティ設定と合わせます。
ロギングレベルは「*」を設定します。


syslogの設定を変更したのでsyslogデーモンを再起動します。

[root@master ~]# /etc/init.d/syslog restart


syslogのログローテーション設定を変更し、slonyのログがローテーションされるようにします。
以下ファイルを修正します。

/etc/logrotate.d/syslog

/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron /var/log/slon_master.log{
    sharedscripts
    postrotate
	/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
	/bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

※1行目へ「/var/log/slon_master.log」を追記



スレーブサーバー下準備

レプリケーションするマスターサーバーのDBと同じスキーマを持つDB(DB名はslave)をスレーブサーバーに作成します。
ユーザ作成と権限も合わせます。

まず、マスターサーバーからDBのユーザ情報とスキーマをダンプします。

[root@master ~]# su - postgres
-bash-3.2$ pg_dump -s master > /tmp/master.schema


ユーザ情報を表示させます。

-bash-3.2$ psql
psql (8.4.5)
Type "help" for help.

postgres=# SELECT * FROM pg_shadow;
 usename  | usesysid | usecreatedb | usesuper | usecatupd | passwd | valuntil | useconfig
----------+----------+-------------+----------+-----------+--------+----------+-----------
 postgres |       10 | t           | t        | t         |        |          |
 hoge     |    16386 | t           | t        | t         |        |          |
(2 rows)

postgres=#

ユーザ名と権限状態をメモしておきます。


次にスレーブサーバーへDBとユーザ作成、スキーマのリストアを行います。

[root@slave ~]# su - postgres
-bash-3.2$ createdb slave
メッセージ後で
-bash-3.2$ createuser hoge
Shall the new role be a superuser? (y/n) y


マスターサーバーから取得したスキーマをリストアします。

[root@slave ~]# su - postgres
-bash-3.2$ psql slave < /tmp/master.schema

これでスレーブサーバーにマスターサーバーと同じスキーマを持つDBが作成されました。


次にファイル名を「master.sh」としたスクリプトファイルを準備します。

#!/bin/sh
CLUSTERNAME=slony_test
DB1=master
DB2=slave
HOST1=10.0.0.1
HOST2=10.0.0.2
RUSER=postgres
slonik <<_EOF_
cluster name = $CLUSTERNAME;
node 1 admin conninfo = 'dbname=$DB1 host=$HOST1 user=$RUSER';
node 2 admin conninfo = 'dbname=$DB2 host=$HOST2 user=$RUSER';
subscribe set ( id = 1, provider = 1, receiver = 2, forward = no);
_EOF_


実行権限を付けておきます。

[root@slave ~]# chmod +x slave.sh


スレーブサーバーslonyログ出力設定

slonyのログ設定を行います。
以下のファイルを編集します。(変更部分と特記事項のみ抜粋)

/etc/slon.conf

# Debug log level (higher value ==> more output).  Range: [0,4], default 4
#log_level=4 #ログの出力はとりあえず全て出力したいのでデフォルトのままの4にしておく。


# If this parameter is 1, messages go both to syslog and the standard 
# output. A value of 2 sends output only to syslog (some messages will 
# still go to the standard output/error).  The default is 0, which means 
# syslog is off.  
# Range:  [0-2], default: 0
#syslog=0
syslog=2 #ログをsyslogにのみ出力するので2へ変更


# Sets the syslog "facility" to be used when syslog enabled.  Valid 
# values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
#syslog_facility=LOCAL0
syslog_facility=LOCAL0 #syslogのログをLOCAL0へ出力(マスター/スレーブを同一ホストで動かす場合は数値をずらす)


# Sets the program name used to identify slon messages in syslog.
#syslog_ident=slon
syslog_ident=slon_slave #slaveのログと分かるように変更


syslogのログ出力設定を行います。

/etc/syslog.conf
syslog設定ファイルへ以下を追記します。

# slony log
local0.*					/var/log/slon_master.log

※「local0.*」の部分は/etc/slon.confのロギングファシリティ設定と合わせます。
ロギングレベルは「*」を設定します。


syslogの設定を変更したのでsyslogデーモンを再起動します。

[root@slave ~]# /etc/init.d/syslog restart


syslogのログローテーション設定を変更し、slonyのログがローテーションされるようにします。
以下ファイルを修正します。

/etc/logrotate.d/syslog

/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron /var/log/slon_slave.log{
    sharedscripts
    postrotate
	/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
	/bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

※1行目へ「/var/log/slon_slave.log」を追記



これでマスター/スレーブ両サーバーの下準備は完了しました。

レプリケーションの開始

マスターサーバーとスレーブサーバーそれぞれで下準備しておいたスクリプトファイルとslonコマンドを次の順番で実行します。

1. マスターサーバーでスクリプトファイルを実行します。

[root@master ~]# ./master.sh



2. マスターサーバーでslonコマンドを実行します。

[root@master ~]# nohup slon -f /etc/slon.conf slony_test "dbname=master user=postgres host=10.0.0.1" &



3. スレーブサーバーでslonコマンドを実行します。

[root@slave ~]# nohup slon -f /etc/slon.conf slony_test "dbname=slave user=postgres host=10.0.0.2" &

これでそれぞれにslonデーモンが起動します。
ですが、データの同期は行われません。
データを同期を開始するには、スレーブサーバーでスクリプトファイルを実行します。


4. スレーブサーバーでスクリプトファイルを実行します。

[root@slave ~]# ./slave.sh

以上でレプリケーションが開始されます。

http://journal.mycom.co.jp/column/yetanother/031/index.html



スレーブサーバーのslonyログに以下のようなログが出力されていきます。
異常ではなく、正常の出力の模様。

2011-04-08 19:08:06 JSTINFO   remoteWorkerThread_1: SYNC 5000009336 done in 0.004 seconds
2011-04-08 19:08:08 JSTINFO   remoteWorkerThread_1: syncing set 1 with 1 table(s) from provider 1
2011-04-08 19:08:08 JSTINFO   remoteWorkerThread_1: SYNC 5000009337 done in 0.004 seconds
2011-04-08 19:08:10 JSTINFO   remoteWorkerThread_1: syncing set 1 with 1 table(s) from provider 1
2011-04-08 19:08:10 JSTINFO   remoteWorkerThread_1: SYNC 5000009338 done in 0.005 secons
2011-04-08 19:08:12 JSTINFO   remoteWorkerThread_1: syncing set 1 with 1 table(s) from provider 1



追記
肝心の参考させて頂いた(丸パクリ)させて頂いたサイトのURLを記載を忘れていました。
http://journal.mycom.co.jp/column/yetanother/031/index.html

追記事項があれば追記、または別記事を書いていきます。