Thu Jan 3 14:42:49 PST 2008
- Previous message: [Slony1-commit] slony1-engine RELEASE-2.0
- Next message: [Slony1-commit] slony1-engine/tools/altperl slony_show_configuration.pl
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Update of /home/cvsd/slony1/slony1-engine/doc/adminguide
In directory main.slony.info:/tmp/cvs-serv23112
Modified Files:
Tag: REL_1_2_STABLE
schemadoc.xml
Log Message:
Bring schemadoc.xml up to date, and address bug #29
http://www.slony.info/bugzilla/show_bug.cgi?id=29
Index: schemadoc.xml
===================================================================
RCS file: /home/cvsd/slony1/slony1-engine/doc/adminguide/schemadoc.xml,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.2
diff -C2 -d -r1.7.2.1 -r1.7.2.2
*** schemadoc.xml 28 Aug 2007 19:18:12 -0000 1.7.2.1
--- schemadoc.xml 3 Jan 2008 22:42:46 -0000 1.7.2.2
***************
*** 3034,3037 ****
--- 3034,3126 ----
+ <!-- Function add_empty_table_to_replication( integer, integer, text, text, text, text ) -->
+ <section id="function.add-empty-table-to-replication-integer-integer-text-text-text-text"
+ xreflabel="schemadocadd_empty_table_to_replication( integer, integer, text, text, text, text )">
+ <title id="function.add-empty-table-to-replication-integer-integer-text-text-text-text-title">
+ add_empty_table_to_replication( integer, integer, text, text, text, text )
+ </title>
+ <titleabbrev id="function.add-empty-table-to-replication-integer-integer-text-text-text-text-titleabbrev">
+ add_empty_table_to_replication( integer, integer, text, text, text, text )
+ </titleabbrev>
+
+ <para>
+ <segmentedlist>
+ <title>Function Properties</title>
+ <?dbhtml list-presentation="list"?>
+ <segtitle>Language</segtitle>
+ <segtitle>Return Type</segtitle>
+ <seglistitem>
+ <seg>PLPGSQL</seg>
+ <seg>bigint</seg>
+ </seglistitem>
+ </segmentedlist>
+
+ Verify that a table is empty, and add it to replication.
+ tab_idxname is optional - if NULL, then we use the primary key.
+ <programlisting>
+ declare
+ p_set_id alias for $1;
+ p_tab_id alias for $2;
+ p_nspname alias for $3;
+ p_tabname alias for $4;
+ p_idxname alias for $5;
+ p_comment alias for $6;
+
+ prec record;
+ v_origin int4;
+ v_isorigin boolean;
+ v_fqname text;
+ v_query text;
+ v_rows integer;
+ v_idxname text;
+
+ begin
+ -- Need to validate that the set exists; the set will tell us if this is the origin
+ select set_origin into v_origin from sl_set where set_id = p_set_id;
+ if not found then
+ raise exception 'add_empty_table_to_replication: set % not found!', p_set_id;
+ end if;
+
+ -- Need to be aware of whether or not this node is origin for the set
+ v_isorigin := ( v_origin = getLocalNodeId('_schemadoc') );
+
+ v_fqname := '"' || p_nspname || '"."' || p_tabname || '"';
+ -- Take out a lock on the table
+ v_query := 'lock ' || v_fqname || ';';
+ execute v_query;
+
+ if v_isorigin then
+ -- On the origin, verify that the table is empty, failing if it has any tuples
+ v_query := 'select 1 as tuple from ' || v_fqname || ' limit 1;';
+ execute v_query into prec;
+ GET DIAGNOSTICS v_rows = ROW_COUNT;
+ if v_rows = 0 then
+ raise notice 'add_empty_table_to_replication: table % empty on origin - OK', v_fqname;
+ else
+ raise exception 'add_empty_table_to_replication: table % contained tuples on origin node %', v_fqname, v_origin;
+ end if;
+ else
+ -- On other nodes, TRUNCATE the table
+ v_query := 'truncate ' || v_fqname || ';';
+ execute v_query;
+ end if;
+ -- If p_idxname is NULL, then look up the PK index, and RAISE EXCEPTION if one does not exist
+ if p_idxname is NULL then
+ select c2.relname into prec from pg_catalog.pg_index i, pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_namespace n where i.indrelid = c1.oid and i.indexrelid = c2.oid and c1.relname = p_tabname and i.indisprimary and n.nspname = p_nspname and n.oid = c1.relnamespace;
+ if not found then
+ raise exception 'add_empty_table_to_replication: table % has no primary key and no candidate specified!', v_fqname;
+ else
+ v_idxname := prec.relname;
+ end if;
+ else
+ v_idxname := p_idxname;
+ end if;
+ perform setAddTable_int(p_set_id, p_tab_id, v_fqname, v_idxname, p_comment);
+ return alterTableRestore(p_tab_id);
+ end
+ </programlisting>
+ </para>
+ </section>
+
<!-- Function add_missing_table_field( text, text, text, text ) -->
<section id="function.add-missing-table-field-text-text-text-text"
***************
*** 6677,6681 ****
<!-- Function logtrigger( ) -->
<section id="function.logtrigger"
! xreflabel="schemadoclogtrigger( )">
<title id="function.logtrigger-title">
logtrigger( )
--- 6766,6770 ----
<!-- Function logtrigger( ) -->
<section id="function.logtrigger"
! xreflabel="schemadoc.logtrigger( )">
<title id="function.logtrigger-title">
logtrigger( )
***************
*** 7286,7321 ****
<programlisting>
declare
! v_receiver record ;
! v_provider record ;
! v_origin record ;
! v_reachable int4[] ;
begin
-- First remove the entire configuration
delete from sl_listen;
! -- Loop over every possible pair of receiver and provider
! for v_receiver in select no_id from sl_node loop
! for v_provider in select pa_server as no_id from 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 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 sl_subscribe
! join 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 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 ;
--- 7375,7461 ----
<programlisting>
declare
! v_row record;
! skip boolean;
begin
-- First remove the entire configuration
delete from sl_listen;
! -- Second populate the sl_listen configuration with a full
! -- network of all possible paths.
! insert into sl_listen
! (li_origin, li_provider, li_receiver)
! select pa_server, pa_server, pa_client from sl_path;
! while true loop
! insert into sl_listen
! (li_origin, li_provider, li_receiver)
! select distinct li_origin, pa_server, pa_client
! from sl_listen, sl_path
! where li_receiver = pa_server
! and li_origin <> pa_client
! except
! select li_origin, li_provider, li_receiver
! from 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 sl_node as N1, sl_node as N2
+ where N1.no_id <> N2.no_id
+ loop
+ skip := 'f';
+ -- 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 sl_set, 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 sl_listen
+ where li_origin = v_row.origin
+ and li_receiver = v_row.receiver;
+ insert into sl_listen (li_origin, li_provider, li_receiver)
+ values (v_row.origin, v_row.origin, v_row.receiver);
+ skip := 't';
+ end if;
! if skip then
! skip := 'f';
! else
! -- 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 sl_set, 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 sl_listen
! where li_origin = v_row.origin
! and li_receiver = v_row.receiver;
! insert into sl_listen (li_origin, li_provider, li_receiver)
! select distinct set_origin, sub_provider, v_row.receiver
! from sl_set, sl_subscribe
! where set_origin = v_row.origin
! and sub_set = set_id
! and sub_receiver = v_row.receiver
! and sub_active;
! end if;
! end if;
end loop ;
***************
*** 7661,7664 ****
--- 7801,7863 ----
</section>
+ <!-- Function replicate_partition( integer, text, text, text, text ) -->
+ <section id="function.replicate-partition-integer-text-text-text-text"
+ xreflabel="schemadocreplicate_partition( integer, text, text, text, text )">
+ <title id="function.replicate-partition-integer-text-text-text-text-title">
+ replicate_partition( integer, text, text, text, text )
+ </title>
+ <titleabbrev id="function.replicate-partition-integer-text-text-text-text-titleabbrev">
+ replicate_partition( integer, text, text, text, text )
+ </titleabbrev>
+
+ <para>
+ <segmentedlist>
+ <title>Function Properties</title>
+ <?dbhtml list-presentation="list"?>
+ <segtitle>Language</segtitle>
+ <segtitle>Return Type</segtitle>
+ <seglistitem>
+ <seg>PLPGSQL</seg>
+ <seg>bigint</seg>
+ </seglistitem>
+ </segmentedlist>
+
+ Add a partition table to replication.
+ tab_idxname is optional - if NULL, then we use the primary key.
+ This function looks up replication configuration via the parent table.
+ <programlisting>
+ declare
+ p_tab_id alias for $1;
+ p_nspname alias for $2;
+ p_tabname alias for $3;
+ p_idxname alias for $4;
+ p_comment alias for $5;
+
+ prec record;
+ prec2 record;
+ v_set_id int4;
+
+ begin
+ -- Look up the parent table; fail if it does not exist
+ select c1.oid into prec from pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_inherits i, pg_catalog.pg_namespace n where c1.oid = i.inhparent and c2.oid = i.inhrelid and n.oid = c2.relnamespace and n.nspname = p_nspname and c2.relname = p_tabname;
+ if not found then
+ raise exception 'replicate_partition: No parent table found for %.%!', p_nspname, p_tabname;
+ end if;
+
+ -- The parent table tells us what replication set to use
+ select tab_set into prec2 from sl_table where tab_reloid = prec.oid;
+ if not found then
+ raise exception 'replicate_partition: Parent table % for new partition %.% is not replicated!', prec.oid, p_nspname, p_tabname;
+ end if;
+
+ v_set_id := prec2.tab_set;
+
+ -- Now, we have all the parameters necessary to run add_empty_table_to_replication...
+ return add_empty_table_to_replication(v_set_id, p_tab_id, p_nspname, p_tabname, p_idxname, p_comment);
+ end
+ </programlisting>
+ </para>
+ </section>
+
<!-- Function sequencelastvalue( text ) -->
<section id="function.sequencelastvalue-text"
***************
*** 9092,9096 ****
<programlisting>
begin
! return 11;
end;
</programlisting>
--- 9291,9295 ----
<programlisting>
begin
! return 12;
end;
</programlisting>
- Previous message: [Slony1-commit] slony1-engine RELEASE-2.0
- Next message: [Slony1-commit] slony1-engine/tools/altperl slony_show_configuration.pl
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Slony1-commit mailing list