Christopher B. Browne's Home Page
cbbrowne@acm.org

8.82. moveset_int(integer, integer, integer, bigint)

Function Properties

PLPGSQLinteger
moveSet(set_id, old_origin, new_origin, wait_seqno) Process MOVE_SET event to request that the origin for set set_id be moved from old_origin to node new_origin
    declare
    	p_set_id			alias for $1;
    	p_old_origin		alias for $2;
    	p_new_origin		alias for $3;
    	p_wait_seqno		alias for $4;
    	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
    	-- ----
    	-- Grab the central configuration lock
    	-- ----
    	lock table sl_config_lock;
    
    	-- ----
    	-- Get our local node ID
    	-- ----
    	v_local_node_id := getLocalNodeId('_schemadoc');
    
    	-- On the new origin, raise an event - ACCEPT_SET
    	if v_local_node_id = p_new_origin then
    		-- Create a SYNC event as well so that the ACCEPT_SET has
    		-- the same snapshot as the last SYNC generated by the new
    		-- origin. This snapshot will be used by other nodes to
    		-- finalize the setsync status.
    		perform createEvent('_schemadoc', 'SYNC', NULL);
    		perform createEvent('_schemadoc', 'ACCEPT_SET', 
    			p_set_id::text, p_old_origin::text, 
    			p_new_origin::text, p_wait_seqno::text);
    	end if;
    
    	-- ----
    	-- Next we have to reverse the subscription path
    	-- ----
    	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
    		-- ----
    		-- Tracing node by node, the old receiver is now in
    		-- v_sub_last and the old provider is in v_sub_node.
    		-- ----
    
    		-- ----
    		-- Get the current provider of this node as next
    		-- and change the provider to the previous one in
    		-- the reverse chain.
    		-- ----
    		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;
    
    	-- ----
    	-- This includes creating a subscription for the old origin
    	-- ----
    	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_snapshot, ssy_action_list)
    					select p_set_id, p_new_origin, v_last_sync,
    					ev_snapshot, 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_snapshot, ssy_action_list)
    					values (p_set_id, p_new_origin, '0',
    					'1:1:', NULL);
    		end if;
    	end if;
    
    	-- ----
    	-- Now change the ownership of the set.
    	-- ----
    	update sl_set
    			set set_origin = p_new_origin
    			where set_id = p_set_id;
    
    	-- ----
    	-- On the new origin, delete the obsolete setsync information
    	-- and the subscription.
    	-- ----
    	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
    			--
    			-- On every other node, change the setsync so that it will
    			-- pick up from the new origins last known sync.
    			--
    			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_snapshot, ssy_action_list)
    						select p_set_id, p_new_origin, v_last_sync,
    						ev_snapshot, 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_snapshot, ssy_action_list)
    						values (p_set_id, p_new_origin,
    						'0', '1:1:', NULL);
    			end if;
    		end if;
    	end if;
    	delete from sl_subscribe
    			where sub_set = p_set_id
    			and sub_receiver = p_new_origin;
    
    	-- Regenerate sl_listen since we revised the subscriptions
    	perform RebuildListenEntries();
    
    	-- Run addPartialLogIndices() to try to add indices to unused sl_log_? table
    	perform addPartialLogIndices();
    
    	-- ----
    	-- If we are the new or old origin, we have to
    	-- adjust the log and deny access trigger configuration.
    	-- ----
    	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 alterTableConfigureTriggers(v_tab_row.tab_id);
    		end loop;
    	end if;
    
    	return p_set_id;
    end;

Google

If this was useful, let others know by an Affero rating

Contact me at cbbrowne@acm.org