Sun Jul 29 13:15:43 PDT 2007
- Previous message: [Slony1-commit] slony1-engine/src/slon remote_worker.c
- Next message: [Slony1-commit] slony1-engine/src/ducttape test_2_pgbench.in
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Update of /home/cvsd/slony1/slony1-engine/src/backend In directory main.slony.info:/tmp/cvs-serv8012/src/backend Modified Files: slony1_funcs.sql Log Message: Rewrote rebuildListenEntries() from scratch. The goal here is to suppress listen entries that would cause events to arrive on cascaded subscribers on a different path around the data provider for the subscription. Jan Index: slony1_funcs.sql =================================================================== RCS file: /home/cvsd/slony1/slony1-engine/src/backend/slony1_funcs.sql,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** slony1_funcs.sql 29 Jul 2007 17:37:34 -0000 1.116 --- slony1_funcs.sql 29 Jul 2007 20:15:41 -0000 1.117 *************** *** 4675,4710 **** as ' declare ! v_receiver record ; ! v_provider record ; ! v_origin record ; ! v_reachable int4[] ; begin -- First remove the entire configuration delete from @NAMESPACE at .sl_listen; ! -- Loop over every possible pair of receiver and provider ! for v_receiver in select no_id from @NAMESPACE at .sl_node loop ! for v_provider in select pa_server as no_id from @NAMESPACE at .sl_path where pa_client = v_receiver.no_id loop ! -- Find all nodes that v_provider.no_id can receiver events from without using v_receiver.no_id ! for v_origin in select * from @NAMESPACE at .ReachableFromNode(v_provider.no_id, array[v_receiver.no_id]) as r(no_id) loop ! -- If v_receiver.no_id subscribes a set from v_provider.no_id, events have to travel the same ! -- path as the data. Ignore possible sl_listen that would break that rule. ! perform 1 from @NAMESPACE at .sl_subscribe ! join @NAMESPACE at .sl_set on sl_set.set_id = sl_subscribe.sub_set ! where ! sub_receiver = v_receiver.no_id and ! sub_provider != v_provider.no_id and ! set_origin = v_origin.no_id ; ! if not found then ! insert into @NAMESPACE at .sl_listen (li_receiver, li_provider, li_origin) ! values (v_receiver.no_id, v_provider.no_id, v_origin.no_id) ; ! end if ; ! end loop ; - end loop ; end loop ; --- 4675,4756 ---- as ' declare ! v_row record; begin -- First remove the entire configuration delete from @NAMESPACE at .sl_listen; ! -- Second populate the sl_listen configuration with a full ! -- network of all possible paths. ! insert into @NAMESPACE at .sl_listen ! (li_origin, li_provider, li_receiver) ! select pa_server, pa_server, pa_client from @NAMESPACE at .sl_path; ! while true loop ! insert into @NAMESPACE at .sl_listen ! (li_origin, li_provider, li_receiver) ! select distinct li_origin, pa_server, pa_client ! from @NAMESPACE at .sl_listen, @NAMESPACE at .sl_path ! where li_receiver = pa_server ! and li_origin <> pa_client ! except ! select li_origin, li_provider, li_receiver ! from @NAMESPACE at .sl_listen; ! if not found then ! exit; ! end if; ! end loop; ! -- We now replace specific event-origin,receiver combinations ! -- with a configuration that tries to avoid events arriving at ! -- a node before the data provider actually has the data ready. + -- Loop over every possible pair of receiver and event origin + for v_row in select N1.no_id as receiver, N2.no_id as origin + from @NAMESPACE at .sl_node as N1, @NAMESPACE at .sl_node as N2 + where N1.no_id <> N2.no_id + loop + -- 1st choice: + -- If we use the event origin as a data provider for any + -- set that originates on that very node, we are a direct + -- subscriber to that origin and listen there only. + if exists (select true from @NAMESPACE at .sl_set, @NAMESPACE at .sl_subscribe + where set_origin = v_row.origin + and sub_set = set_id + and sub_provider = v_row.origin + and sub_receiver = v_row.receiver + and sub_active) + then + delete from @NAMESPACE at .sl_listen + where li_origin = v_row.origin + and li_receiver = v_row.receiver; + insert into @NAMESPACE at .sl_listen (li_origin, li_provider, li_receiver) + values (v_row.origin, v_row.origin, v_row.receiver); + continue; + end if; ! -- 2nd choice: ! -- If we are subscribed to any set originating on this ! -- event origin, we want to listen on all data providers ! -- we use for this origin. We are a cascaded subscriber ! -- for sets from this node. ! if exists (select true from @NAMESPACE at .sl_set, @NAMESPACE at .sl_subscribe ! where set_origin = v_row.origin ! and sub_set = set_id ! and sub_receiver = v_row.receiver ! and sub_active) ! then ! delete from @NAMESPACE at .sl_listen ! where li_origin = v_row.origin ! and li_receiver = v_row.receiver; ! insert into @NAMESPACE at .sl_listen (li_origin, li_provider, li_receiver) ! select distinct set_origin, sub_provider, v_row.receiver ! from @NAMESPACE at .sl_set, @NAMESPACE at .sl_subscribe ! where set_origin = v_row.origin ! and sub_set = set_id ! and sub_receiver = v_row.receiver ! and sub_active; ! continue; ! end if; end loop ; *************** *** 4722,4766 **** -- ---------------------------------------------------------------------- - -- FUNCTION ReachableFromNode (receiver, blacklist) - -- - -- ---------------------------------------------------------------------- - create or replace function @NAMESPACE at .ReachableFromNode(int4, int4[]) returns setof int4 as ' - declare - v_node alias for $1 ; - v_blacklist alias for $2 ; - v_ignore int4[] ; - v_reachable_edge_last int4[] ; - v_reachable_edge_new int4[] default ''{}'' ; - v_server record ; - begin - v_reachable_edge_last := array[v_node] ; - v_ignore := v_blacklist || array[v_node] ; - return next v_node ; - while v_reachable_edge_last != ''{}'' loop - v_reachable_edge_new := ''{}'' ; - for v_server in select pa_server as no_id - from @NAMESPACE at .sl_path - where pa_client = ANY(v_reachable_edge_last) and pa_server != ALL(v_ignore) - loop - if v_server.no_id != ALL(v_ignore) then - v_ignore := v_ignore || array[v_server.no_id] ; - v_reachable_edge_new := v_reachable_edge_new || array[v_server.no_id] ; - return next v_server.no_id ; - end if ; - end loop ; - v_reachable_edge_last := v_reachable_edge_new ; - end loop ; - return ; - end ; - ' language 'plpgsql'; - - comment on function @NAMESPACE at .ReachableFromNode(int4, int4[]) is - 'ReachableFromNode(receiver, blacklist) - - Find all nodes that <receiver> can receive events from without - using nodes in <blacklist> as a relay.'; - - - -- ---------------------------------------------------------------------- -- FUNCTION generate_sync_event (interval) -- --- 4768,4771 ----
- Previous message: [Slony1-commit] slony1-engine/src/slon remote_worker.c
- Next message: [Slony1-commit] slony1-engine/src/ducttape test_2_pgbench.in
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Slony1-commit mailing list