関数特性
言語: 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;