postgreSQLのレプリケーションツールslony-IでWindowsサーバーとLinuxサーバーを連携

WindowsServerとLinuxサーバ間でpostgreSQLレプリケーションを取る必要があったので、レプリケーションができるツールについていろいろ調べてみた。

PGCluster(マルチマスタ)
pgpool(マルチマスタ)
PostgresForest(マルチマスタ)
Slony-l(マスタスレーブ)

上記のレプリケーションソフトウェアのなかで、Windowsでも使えるのはSlony-lだけだった。

というわけで、以下はSlony-lのインストール&設定のやりかたです。

インストール(Windows

http://www.slony.info/downloads/1.2/win32/slony-I-1.2.12R-pg82.zipよりインストーラーをダウンロード
インストーラーを実行したら完了です。

インストール(Linux

wget http://www.slony.info/downloads/1.2/source/slony1-1.2.14.tar.bz2

tar jxv slony1-1.2.14.tar.bz2

cd slony1-1.2.14

PGMAIN=/usr/local/pgsql/8.2 \
./configure \
    --prefix=$PGMAIN \
    --bindir=$PGMAIN/bin \
    --datadir=$PGMAIN/share \
    --libdir=$PGMAIN/lib \
    --with-pgconfigdir=$PGMAIN/bin \
    --with-pgbindir=$PGMAIN/bin \
    --with-pgincludedir=$PGMAIN/include \
    --with-pglibdir=$PGMAIN/lib \
    --with-pgsharedir=$PGMAIN/share
make all; make install

インストール中に以下のようなエラーが出た場合、

Missing yacc parser.y parser.c
make[2]: *** [parser.c] エラー 1
make[2]: ディレクトリ `/usr/local/src/slony1-1.2.15/src/slony_logshipper' から出ます
make[1]: *** [all] エラー 2
make[1]: ディレクトリ `/usr/local/src/slony1-1.2.15/src' から出ます
make: *** [all] エラー 2

このエラーの原因はflexとbisonがインストールされていない場合に起こるようなので、flexとbisonをインストール

$ yum -y install flex bison

flexとbisonをインストールしたら、再びSlony-lインストールコマンドを実行します。

設定(Windows

以下のスクリプトを作成
setup_cluster.txt

#レプリケーションシステムが使用する名前空間の定義
cluster name = test1;
#クラスタのそれぞれのノードにノード1が接続するための定義
node 1 admin conninfo = 'dbname=node1 host=localhost user=postgres';
node 2 admin conninfo = 'dbname=node2 host=localhost user=postgres';
#最初のノードを初期化します。idは1を指定(最初は1でないといけない)
#この処理でこのレプケーションシステム特有のスキーマ_$CLUSTERNAME(_slony_test1)を作成
init cluster ( id = 1, comment = 'node 1' );
table add key ( node id = 1, fully qualified name = 'public.history' ); 
create set ( id = 1, origin = 1, comment = 'all pgbench tables' );
#Slony-Iはテーブルをセットに編成します。
#以下のコマンドで全ての1つのtable1を含む1つのセットが作成されます。
set add table ( set id = 1, origin = 1, id = 1, fully qualified name = 'public.accounts', comment = 'table accounts' );
set add table ( set id = 1, origin = 1, id = 2, fully qualified name = 'public.branches', comment = 'table branches' );
set add table ( set id = 1, origin = 1, id = 3, fully qualified name = 'public.tellers', comment = 'table tellers' );
set add table ( set id = 1, origin = 1, id = 4, fully qualified name = 'public.history', key = serial, comment = 'table history' ); 
#2番目のノード(スレーブ)を作成し、2つのノードがどのように接続し、また、
#どのように事象を監視するかを指示します。
store node ( id = 2, comment = 'node 2' );
store path ( server = 1, client = 2, conninfo = 'dbname=node1 host=localhost user=postgres');
store path ( server = 2, client = 1, conninfo = 'dbname=node2 host=localhost user=postgres');
store listen ( origin = 1, provider = 1, receiver = 2 );
store listen ( origin = 2, provider = 2, receiver = 1 );

ファイル作成後、slonikコマンドを実行

slonik setup_cluster.txt

sloneデーモンの起動

slon test1 "dbname=node1 user=postgres"&

設定(Linux

sloneデーモンの起動

$ slon test1 "dbname=node2 user=postgres"&

以上で設定は完了

実行

マスタとなるWindowサーバに以下のスクリプトファイルを作成します。
sl_start.txt

cluster name = test1; 
node 1 admin conninfo = 'dbname=node1 host=localhost user=postgres';
node 2 admin conninfo = 'dbname=node2 host=localhost user=postgres'; 
subscribe set ( id = 1,provider = 1,receiver = 2,forward = no);

slonikコマンドを実行し、同期開始

slonik sl_start.txt 

以上でレプリケーション設定が完了〜

差分チェック(Linux

レプリケーションが完全に行われているかどうかのチェックは以下のスクリプト
作成してチェックします。
compare.sh

#!/bin/sh

CLUSTER=test1
DBNAME1=node1
DBNAME2=node2
HOST1=192.168.0.98
HOST2=192.168.0.99
SLONY_USER=postgres
PGBENCH_USER=postgres

echo -n "**** comparing sample1 ... "
echo -n "**** dump for node1 ... "
psql -U $PGBENCH_USER -h $HOST1 $DBNAME1 >dump.tmp.1.$$ <<_EOF_
  select 'accounts:'::text,aid,bid,abalance,filler
    from accounts order by aid;
  select 'branches:'::text,bid,bbalance,filler
    from branches order by bid;
  select 'tellers:'::text,tid,bid,tbalance,filler
    from tellers order by tid;
  select 'history:'::text,tid,bid,aid,delta,mtime,filler,
    "_Slony-I_${CLUSTER}_rowID"
    from history order by "_Slony-I_${CLUSTER}_rowID";
_EOF_

echo -n "**** dump for node2 ... "
psql -U $PGBENCH_USER -h $HOST2 $DBNAME2 >dump.tmp.2.$$ <<_EOF_
  select 'accounts:'::text,aid,bid,abalance,filler
    from accounts order by aid;
  select 'branches:'::text,bid,bbalance,filler
    from branches order by bid;
  select 'tellers:'::text,tid,bid,tbalance,filler
    from tellers order by tid;
  select 'history:'::text,tid,bid,aid,delta,mtime,filler,
    "_Slony-I_${CLUSTER}_rowID"
    from history order by "_Slony-I_${CLUSTER}_rowID";
_EOF_

if diff dump.tmp.1.$$ dump.tmp.2.$$ >test_1.diff ; then
  echo "success - databases are equal."
  rm dump.tmp.?.$$
  rm test_1.diff
else
  echo "FAILED - see test_1.diff for database differences"
fi