[pgsql-jp: 27624] Re: データベース間のリレーションの図り方

Masaru Sugawara rk73 @ sea.plala.or.jp
2002年 10月 13日 (日) 12:09:25 JST


すがわらです。

> んーと、リモートとローカルでどういう順にbeginをかけるかによると思うのですが、
> 例えば、リモート→ローカルという順番でトランザクションを始める場合に、
> 
> リモートにbeginかけて、何らかの理由でレスポンスが遅れてる間に
> ローカルでは他のトランザクションによってデータが更新されて、
> その後ローカルにbeginする、とかというのは、ローカルとリモートでbeginが始まる
> タイミングが大きくズレる場合がありますよね?
> 
> 本来ならリモートでbeginするのと同時にローカルでもトランザクションを開始して
> ほしいわけですが、「双方にbeginを発行するタイムラグ」が問題になることは
> 無いのかなぁ、と。

 ローカル→リモートの順でbeginをかけるとタイムラグを吸収しているように見
 えました。石井さんがおっしゃっているように、libpqの動作として、BEGINが
 完了するまでブロックしているのではないでしょうか。いろいろな場合を想定
 したわけではありませんが、リモート側のテーブルを先にロックしておくと、
 それが解除されるまでローカル側のクエリーが待っていてくれるようです。





$ cd ../postgresql-7.3.b2/contrib/dblink
$ createdb regression_slave
$ createdb regression_master
$ createlang plpgsql regression_master
$ psql regression_slave

\i dblink.sql
create table foo(f1 int, f2 text, f3 text[], primary key (f1,f2));
insert into foo values(0,'a','{"a0","b0","c0"}');
insert into foo values(1,'b','{"a1","b1","c1"}');

\connect regression_master;
\i dblink.sql
create table foo(f1 int, f2 text, f3 text[], primary key (f1,f2));
insert into foo values(0,'a','{"a0","b0","c0"}');
insert into foo values(1,'b','{"a1","b1","c1"}');

create or replace function fn_mirror() returns text as '
declare
  ret text;
begin
  perform dblink_connect(''dbname=regression_slave'');
  perform dblink_exec(''begin'');
  perform dblink_exec(''insert into foo values(2,''''c'''',''''{"a2","b2","c2"}'''');'');
  select into ret * from
     dblink_exec(''insert into foo values(3,''''d'''',''''{"a3","b3","c3"}'''');'');
  raise notice ''slave : %'', ret;

  insert into foo values(2,''b'',''{"a2","b2","c2"}'');

  perform dblink_exec(''end'');
  perform dblink_disconnect();
  return ''success'';
end;
' language 'plpgsql';


-- ここで、もう1つ窓を開きます。
$ psql regression_slave
regression_slave=# begin;
regression_slave=# lock table foo in share mode;

-- マスター側の窓に移って関数を実行すると、slaveがロックされているので、
-- 待ち状態になります。
regression_master=# select fn_mirror();

-- slaveに移ってロックを外してあげると、master側の関数が実行されます。
regression_slave=# end;
regression_slave=# select * from foo;



-- データベースの削除
$ dropdb regression_slave
$ dropdb regression_master



--------------------------------
  Masaru Sugawara
  e-mail:rk73 @ sea.plala.or.jp
 -------------------------------





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