failoverset_int(p_last_seqno integer, p_backup_node integer, p_failed_node bigint)

8.66. failoverset_int(p_last_seqno integer, p_backup_node integer, p_failed_node bigint)

Function Properties

Language: PLPGSQL

Return Type: integer

FUNCTION failoverSet_int (failed_node, backup_node, set_id, wait_seqno) Finish failover for one set.

declare
	v_row				record;
	v_last_sync			int8;
	v_set				int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table sl_config_lock;

	SELECT max(ev_seqno) into v_last_sync FROM sl_event where
		   ev_origin=p_failed_node;
	if v_last_sync > p_last_seqno then
	   -- this node is ahead of the last sequence number from the
	   -- failed node that the backup node has.
	   -- this node must unsubscribe from all sets from the origin.
	   for v_set in select set_id from sl_set where 
		set_origin=p_failed_node
		loop
			raise warning 'Slony is dropping the subscription of set % found sync %s bigger than %s '
			, v_set, v_last_sync::text, p_last_seqno::text;
			perform unsubscribeSet(v_set,
				   getLocalNodeId('_schemadoc'),
				   true);
		end loop;
		delete from sl_event where ev_origin=p_failed_node
			   and ev_seqno > p_last_seqno;
	end if;
	-- ----
	-- Change the origin of the set now to the backup node.
	-- On the backup node this includes changing all the
	-- trigger and protection stuff
	for v_set in select set_id from sl_set where 
		set_origin=p_failed_node
	loop
	-- ----
	   if p_backup_node = getLocalNodeId('_schemadoc') then
	   	  	delete from sl_setsync
				where ssy_setid = v_set;
			delete from sl_subscribe
				where sub_set = v_set
					and sub_receiver = p_backup_node;
			update sl_set
				set set_origin = p_backup_node
				where set_id = v_set;		
			 update sl_subscribe
						set sub_provider=p_backup_node
					  	FROM sl_node receive_node
					   where sub_set = v_set
					   and sub_provider=p_failed_node
					   and sub_receiver=receive_node.no_id
					   and receive_node.no_failed=false;			

			for v_row in select * from sl_table
				where tab_set = v_set
				order by tab_id
			loop
				perform alterTableConfigureTriggers(v_row.tab_id);
			end loop;
	else
		raise notice 'deleting from sl_subscribe all rows with receiver %',
		p_backup_node;
		
			delete from sl_subscribe
					  where sub_set = v_set
					  and sub_receiver = p_backup_node;
		
			update sl_subscribe
				 		set sub_provider=p_backup_node
						FROM sl_node receive_node
					   where sub_set = v_set
					    and sub_provider=p_failed_node
						 and sub_provider=p_failed_node
					   and sub_receiver=receive_node.no_id
					   and receive_node.no_failed=false;
			update sl_set
					   set set_origin = p_backup_node
				where set_id = v_set;
			-- ----
			-- If we are a subscriber of the set ourself, change our
			-- setsync status to reflect the new set origin.
			-- ----
			if exists (select true from sl_subscribe
			   where sub_set = v_set
			   	and sub_receiver = getLocalNodeId(
						'_schemadoc'))
			then
				delete from sl_setsync
					   where ssy_setid = v_set;

				select coalesce(max(ev_seqno), 0) into v_last_sync
					   from sl_event
					   where ev_origin = p_backup_node
					   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 v_set, p_backup_node, v_last_sync,
					ev_snapshot, NULL
					from sl_event
					where ev_origin = p_backup_node
						and ev_seqno = v_last_sync;
				else
					insert into sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_snapshot, ssy_action_list)
					values (v_set, p_backup_node, '0',
					'1:1:', NULL);
				end if;	
			end if;
		end if;
	end loop;
	
	--If there are any subscriptions with 
	--the failed_node being the provider then
	--we want to redirect those subscriptions
	--to come from the backup node.
	--
	-- The backup node should be a valid
	-- provider for all subscriptions served
	-- by the failed node. (otherwise it
	-- wouldn't be a allowable backup node).
--	delete from sl_subscribe
--		   where sub_receiver=p_backup_node;
		   
	update sl_subscribe	       
	       set sub_provider=p_backup_node
	       from sl_node
	       where sub_provider=p_failed_node
	       and sl_node.no_id=sub_receiver
	       and sl_node.no_failed=false
		   and sub_receiver<>p_backup_node;
		   
	update sl_subscribe	       
	       set sub_provider=(select set_origin from
		   	   sl_set where set_id=
			   sub_set)
			where sub_provider=p_failed_node
			and sub_receiver=p_backup_node;
		   
	update sl_node
		   set no_active=false WHERE 
		   no_id=p_failed_node;

	-- Rewrite sl_listen table
	perform RebuildListenEntries();


	return p_failed_node;
end;