[pgsql-jp: 28404] 7.3の新機能[dbmirror]について

石田雅也 ishida_m @ 15jam.jp
2002年 12月 20日 (金) 21:48:25 JST


石田です。

PostgreSQL7.3からの新機能である、「dbmirro」の実験を行いました。
長くなりますが、結果を報告します。

使用した環境は
・自作PCで、CPU AthlonXP/2100、メモリ 256 x 2、 HD 40G x 2、OS RedHat7.3
・メーカ不明のPC、CPU Celeron800、メモリ 256、HD 30G、 OS RedHat7.3
の2台です。ネットワークは、ローカルLAN/100 で接続しました。

まず、両マシンにPostgreSQL7.3をインストールしました。
この際 --with-perl を付けておかないと、この「dbmirror」は動作しないです。
これはPerlで同期を取っているからです。他のオプションはお好みで。
また、pg_ctlでスタートして、外部からのアクセスを許可します。

1.PsotgreSQLのソースを展開したディレクトリに contrib/dbmirror/ があります。
まず、この中身をコンパイルします。Makefileがあるのでmakeするだけでいいです。
オプションをつけて、どこかにインストールしてもかまわないみたいです。
今回はインストールはせず、使ってみただけです。

2.MirrorSetup.sqlというファイルがありますので、これをDBに保存します。
DB名は「test」で行いました。
> psql test < MirrorSetup.sql

3.slaveDatabase.confというファイルを作成します。
サンプルファイルがあるので、それを編集しただけです。
-----ファイルの中身-----
$masterHost = "マスタDBのホスト名orIPアドレス";
$masterDb = "データベース名";
$masterUser = "マスタDBのPostgreSQLのユーザ名";
$masterPassword = "上のユーザのパスワード";

# Where to email Error messages to
# $errorEmailAddr = "エラー時のメッセージ送信先";

$slaveInfo->{"slaveHost"} = "スレイブDBのホスト名orIPアドレス";
$slaveInfo->{"slaveDb"} = "データベース名";
$slaveInfo->{"slaveUser"} = "スレイブDBのPostgreSQLのユーザ名";
$slaveInfo->{"slavePassword"} = "上のユーザのパスワード";
------------------------
説明を書いてみましたが、ファイルの中身を見ればわかると思います。

4.Triggerのテーブルを作成します。
これもサンプルファイルAddTrigger.sqlがありましたので、編集しました。
-----ファイルの中身-----
SET search_path = public;

SET autocommit TO 'on';

CREATE TRIGGER "テーブル名_Trig"
AFTER INSERT OR DELETE OR UPDATE ON "テーブル名"
FOR EACH ROW EXECUTE PROCEDURE "recordchange" ();
------------------------
変更するのは、日本語で書いた部分だけでいいです。
編集が終了したら、TriggerをDBに登録します。
> psql test < AddTrigger.sql

5.スレイブDBを作成します。
データを受け取るために、同じテーブルをもつDBを作成します。
一番早いのは、マスタDBをdumpしてスレイブでrestoreすることでしょう。

6.マスタDBでMirrorHostにスレイブDBのホストを追加します。
READMEに書いてあった構文を使いました。
#INSERT INTO "MirrorHost" ("HostName") VALUES('スレイブDBのホスト名orIP');

これで準備完了です。
ここまでのことは、README.dbmirrorに全て書いてあります。
もっと詳しく説明が書いてあるので、もっとよく知りたい方はそちらを参照してください。
いよいよ dbmirror を動かしてみます。
マスタDBのマシンで、DBMirror.plに引数slaveDatabase.confをつけて実行しました。
> ./DBMirror.pl slaveDatabase.conf &

ところが、これで実行すると、エラーが出てしまいます。
-----エラー-----
Global symbol "$setResult" requires explicit package name at ./DBMirror.pl line 131.
Global symbol "$setResult" requires explicit package name at ./DBMirror.pl line 132.
Global symbol "$setResult2" requires explicit package name at ./DBMirror.pl line 140.
Global symbol "$setResult2" requires explicit package name at ./DBMirror.pl line 141.
Execution of ./DBMirror.pl aborted due to compilation errors.
----------------
$setResultと$setResult2が宣言されていないらしいので、DBMirror.plを修正しました。

-----DBMirror.pl-----
--line 129 - line 132
  my $setQuery;
  my $setResult; <--- 追加
  $setQuery = "SET search_path = public";
  $setResult = $masterConn->exec($setQuery);
--line 139 - line 142
  my $setQuery2;
  my $setResult2; <--- 追加
  $setQuery2 = "SET autocommit TO 'on'";
  $setResult2 = $masterConn->exec($setQuery2);
---------------------
これで再度実行したら、エラーも出ずに動き始めました。

これで、マスタDBに何かデータを追加してみると、
自動的にスレイブDBにデータが格納されました。

DBMirror.plに待機時間が設定されているので、
これを変更すれば好みの時間で連動が取れるようです。
-----DBMirror.pl-----
--line 150
  while(1) {
    if($firstTime == 0) {
      sleep 60;
    }
---------------------
このsleepを変えるだけです。

今回の実験は本当に連動が取れるかどうかの実験でしたので、これだけです。
次は、実際に運用しているDBの大容量のデータを使って、
ローカルではなくグローバルでやるつもりです。
また、他の機能「dblink」や「oracle」も実験してみるつもりです。

何かアドバイスがありましたら、よろしくお願いします。
とても長くなりましたが、結果報告を終わります。
-- 
石田雅也 <ishida_m @ 15jam.jp>




pgsql-jp メーリングリストの案内