関数特性
言語: PLPGSQL
戻り値: integer
moveSet(set_id, old_origin, new_origin) セット set_id に対するオリジンが old_origin からノード new_origin へ移動させられるように要求する MOVE_SET 事象を処理。declare
p_set_id alias for $1;
p_old_origin alias for $2;
p_new_origin alias for $3;
v_local_node_id int4;
v_tab_row record;
v_sub_row record;
v_sub_node int4;
v_sub_last int4;
v_sub_next int4;
v_last_sync int8;
begin
-- ----
-- 中枢構成にロックの取得
-- ----
lock table sl_config_lock;
-- ----
-- 自分のローカルノード識別子を取得
-- ----
v_local_node_id := getLocalNodeId('_schemadoc');
-- ----
-- 私たちがセットの旧もしくは新オリジンノードであれば、まず最初に
-- 全てのテーブルからログトリガーを削除する日津小があります
-- ----
if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
for v_tab_row in select tab_id from sl_table
where tab_set = p_set_id
order by tab_id
loop
perform alterTableRestore(v_tab_row.tab_id);
end loop;
end if;
-- On the new origin, raise an event - ACCEPT_SET
if v_local_node_id = p_new_origin then
-- Find the event number from the origin
select max(ev_seqno) as seqno into v_sub_row
from sl_event
where ev_type = 'MOVE_SET' and
ev_data1 = p_set_id and
ev_data2 = p_old_origin and
ev_data3 = p_new_origin and
ev_origin = p_old_origin;
perform createEvent('_schemadoc', 'ACCEPT_SET',
p_set_id, p_old_origin, p_new_origin, v_sub_row.seqno);
end if;
-- ----
-- 次に購読経路を反転させる必要があります。
-- ----
v_sub_last = p_new_origin;
select sub_provider into v_sub_node
from sl_subscribe
where sub_set = p_set_id
and sub_receiver = p_new_origin;
if not found then
raise exception 'Slony-I: subscription path broken in moveSet_int';
end if;
while v_sub_node <> p_old_origin loop
-- ----
-- ノード 1 つ 1 つトレースする事で、旧レシーバノードは v_sub_last の中にあり、
-- 、旧プロバイダノードは v_sub_node の中にあります。
-- ----
-- ----
-- 反転連鎖の中で前のプロバイダに対し、引き継ぎの、
-- そしてプロバイダ変更としてこのノードの現在の
-- プロバイダを獲得します。
-- ----
select sub_provider into v_sub_next
from sl_subscribe
where sub_set = p_set_id
and sub_receiver = v_sub_node
for update;
if not found then
raise exception 'Slony-I: subscription path broken in moveSet_int';
end if;
update sl_subscribe
set sub_provider = v_sub_last
where sub_set = p_set_id
and sub_receiver = v_sub_node;
v_sub_last = v_sub_node;
v_sub_node = v_sub_next;
end loop;
-- ----
-- これは旧オリジンに対する購読の作成を含みます。
-- ----
insert into sl_subscribe
(sub_set, sub_provider, sub_receiver,
sub_forward, sub_active)
values (p_set_id, v_sub_last, p_old_origin, true, true);
if v_local_node_id = p_old_origin then
select coalesce(max(ev_seqno), 0) into v_last_sync
from sl_event
where ev_origin = p_new_origin
and ev_type = 'SYNC';
if v_last_sync > 0 then
insert into sl_setsync
(ssy_setid, ssy_origin, ssy_seqno,
ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
select p_set_id, p_new_origin, v_last_sync,
ev_minxid, ev_maxxid, ev_xip, NULL
from sl_event
where ev_origin = p_new_origin
and ev_seqno = v_last_sync;
else
insert into sl_setsync
(ssy_setid, ssy_origin, ssy_seqno,
ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
values (p_set_id, p_new_origin, '0',
'0', '0', '', NULL);
end if;
end if;
-- ----
-- ここでセットの所有者を変更します。
-- ----
update sl_set
set set_origin = p_new_origin
where set_id = p_set_id;
-- ----
-- 新規オリジン上で、使われなくなった setsync 情報と
-- 購読を削除します。
-- ----
if v_local_node_id = p_new_origin then
delete from sl_setsync
where ssy_setid = p_set_id;
else
if v_local_node_id <> p_old_origin then
--
-- 他の全てのノード上で、新規オリジンから最後に知られた sync を
-- 拾いあげるため setsync を変更します。
--
delete from sl_setsync
where ssy_setid = p_set_id;
select coalesce(max(ev_seqno), 0) into v_last_sync
from sl_event
where ev_origin = p_new_origin
and ev_type = 'SYNC';
if v_last_sync > 0 then
insert into sl_setsync
(ssy_setid, ssy_origin, ssy_seqno,
ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
select p_set_id, p_new_origin, v_last_sync,
ev_minxid, ev_maxxid, ev_xip, NULL
from sl_event
where ev_origin = p_new_origin
and ev_seqno = v_last_sync;
else
insert into sl_setsync
(ssy_setid, ssy_origin, ssy_seqno,
ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
values (p_set_id, p_new_origin, '0',
'0', '0', '', NULL);
end if;
end if;
end if;
delete from sl_subscribe
where sub_set = p_set_id
and sub_receiver = p_new_origin;
-- 購読が RebuildListenEntries() を実行するように更新したので sl_listen を再生成します。
-- ----
-- もし私たちが新規もしくは旧オリジンであれば、全てのテーブルを
-- 再び変更された状態にしなければなりません。
-- ----
if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
for v_tab_row in select tab_id from sl_table
where tab_set = p_set_id
order by tab_id
loop
perform alterTableForReplication(v_tab_row.tab_id);
end loop;
end if;
return p_set_id;
end;