CVS User Account cvsuser
Mon Dec 6 23:45:05 PST 2004
Log Message:
-----------
Transformed all Wiki material aside from the FAQ into DocBook SGML

Added Files:
-----------
    slony1-engine/doc/adminguide:
        Makefile (r1.1)
        addthings.sgml (r1.1)
        adminscripts.sgml (r1.1)
        cluster.sgml (r1.1)
        concepts.sgml (r1.1)
        ddlchanges.sgml (r1.1)
        defineset.sgml (r1.1)
        dropthings.sgml (r1.1)
        failover.sgml (r1.1)
        filelist.sgml (r1.1)
        firstdb.sgml (r1.1)
        help.sgml (r1.1)
        installation.sgml (r1.1)
        intro.sgml (r1.1)
        legal.sgml (r1.1)
        listenpaths.sgml (r1.1)
        maintenance.sgml (r1.1)
        monitoring.sgml (r1.1)
        prerequisites.sgml (r1.1)
        reshape.sgml (r1.1)
        slonconfig.sgml (r1.1)
        slonik.sgml (r1.1)
        slony.sgml (r1.1)
        startslons.sgml (r1.1)
        subscribenodes.sgml (r1.1)
        stylesheet-hh.xsl (r1.1)
        stylesheet.css (r1.1)
        stylesheet.dsl (r1.1)
        stylesheet.xsl (r1.1)

-------------- next part --------------
--- /dev/null
+++ doc/adminguide/stylesheet-hh.xsl
@@ -0,0 +1,108 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'
+                xmlns="http://www.w3.org/TR/xhtml1/transitional"
+                exclude-result-prefixes="#default">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/htmlhelp/htmlhelp.xsl"/>
+
+<!-- Parameters -->
+<xsl:param name="htmlhelp.use.hhk" select="'1'"/>
+<xsl:param name="pg.fast" select="'0'"/>
+
+<!--
+<xsl:param name="draft.mode">
+  <xsl:choose>
+    <xsl:when test="contains($pg.version, 'devel')">yes</xsl:when>
+    <xsl:otherwise>no</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+-->
+
+<xsl:param name="show.comments">
+  <xsl:choose>
+    <xsl:when test="contains($pg.version, 'devel')">1</xsl:when>
+    <xsl:otherwise>0</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+
+<xsl:param name="callout.graphics" select="'0'"></xsl:param>
+<xsl:param name="toc.section.depth">2</xsl:param>
+<xsl:param name="linenumbering.extension" select="'0'"></xsl:param>
+<xsl:param name="generate.index" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="preface.autolabel" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="section.autolabel" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="section.label.includes.component.label" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="html.stylesheet" select="'stylesheet.css'"></xsl:param>
+<xsl:param name="use.id.as.filename" select="'1'"></xsl:param>
+<xsl:param name="make.valid.html" select="1"></xsl:param>
+<xsl:param name="generate.id.attributes" select="1"></xsl:param>
+<xsl:param name="generate.legalnotice.link" select="1"></xsl:param>
+<xsl:param name="refentry.xref.manvolnum" select="0"/>
+<xsl:param name="link.mailto.url">pgsql-docs at postgresql.org</xsl:param>
+<xsl:param name="formal.procedures" select="0"></xsl:param>
+<xsl:param name="punct.honorific" select="''"></xsl:param>
+<xsl:param name="chunker.output.indent" select="'yes'"/>
+<xsl:param name="chunk.quietly" select="1"></xsl:param>
+
+
+<!-- Change display of some elements -->
+
+<xsl:template match="command">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="productname">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="structfield">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="structname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="symbol">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="systemitem">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="token">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="type">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="programlisting/emphasis">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+
+<!-- Special support for Tcl synopses -->
+
+<xsl:template match="optional[@role='tcl']">
+  ?<xsl:call-template name="inline.charseq"/>?
+</xsl:template>
+
+
+<!--
+  Format multiple terms in varlistentry vertically, instead
+  of comma-separated.
+ -->
+
+<xsl:template match="varlistentry/term[position()!=last()]">
+  <span class="term">
+    <xsl:call-template name="anchor"/>
+    <xsl:apply-templates/>
+  </span><br/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+++ doc/adminguide/defineset.sgml
@@ -0,0 +1,56 @@
+<article id="defineset"> <title/Defining Slony-I Replication Sets/
+
+
+<para>Defining the nodes indicated the shape of the cluster of database servers; it is now time to determine what data is to be copied between them.  The groups of data that are copied are defined as "sets."
+
+<para>A replication set consists of the following:
+<itemizedlist>
+<listitem><para> Keys on tables that are to be replicated that have no suitable primary key
+
+<listitem><para> Tables that are to be replicated
+
+<listitem><para> Sequences that are to be replicated
+</itemizedlist>
+
+<sect1><title/ Primary Keys/
+
+<para>Slony-I <emphasis/needs/ to have a primary key on each table that is replicated.  PK values are used as the primary identifier for each tuple that is modified in the source system.  There are three ways that you can get Slony-I to use a primary key:
+
+<itemizedlist>
+<listitem><para> If the table has a formally identified primary key, SET ADD TABLE can be used without any need to reference the primary key.  Slony-I will pick up that there is a primary key, and use it.
+
+<listitem><para> If the table hasn't got a primary key, but has some *candidate* primary key, that is, some index on a combination of fields that is UNIQUE and NOT NULL, then you can specify the key, as in
+
+<para><command>SET ADD TABLE (set id = 1, origin = 1, id = 42, full qualified name = 'public.this_table', key = 'this_by_that', comment='this_table has this_by_that as a candidate primary key');
+</command>
+
+<para>	  Notice that while you need to specify the namespace for the table, you must <emphasis/not/ specify the namespace for the key, as it infers the namespace from the table.
+
+<listitem><para> If the table hasn't even got a candidate primary key, you can ask Slony-I to provide one.  This is done by first using TABLE ADD KEY to add a column populated using a  Slony-I sequence, and then having the SET ADD TABLE include the directive key=serial, to indicate that Slony-I's own column should be used.
+
+</itemizedlist>
+<para> It is not terribly important whether you pick a "true" primary key or a mere "candidate primary key;" it is, however, recommended that you have one of those instead of having Slony-I populate the PK column for you.  If you don't have a suitable primary key, that means that the table hasn't got any mechanism from your application's standpoint of keeping values unique.  Slony-I may therefore introduce a new failure mode for your application, and this implies that you had a way to enter confusing data into the database.
+
+<sect1><title/ Grouping tables into sets/
+
+<para> It will be vital to group tables together into a single set if those tables are related via foreign key constraints.  If tables that are thus related are <emphasis/not/ replicated together, you'll find yourself in trouble if you switch the "master provider" from one node to another, and discover that the new "master" can't be updated properly because it is missing the contents of dependent tables.
+
+<para> If a database schema has been designed cleanly, it is likely that replication sets will be virtually synonymous with namespaces.  All of the tables and sequences in a particular namespace will be sufficiently related that you will want to replicate them all.  Conversely, tables found in different schemas will likely NOT be related, and therefore should be replicated in separate sets.
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/adminscripts.sgml
@@ -0,0 +1,181 @@
+<article id="altperl"> <title/Slony Administration Scripts
+
+<para>In the "altperl" directory in the CVS tree, there is a sizable set of Perl scripts that may be used to administer a set of Slony-I instances, which support having arbitrary numbers of nodes.
+
+<para>Most of them generate Slonik scripts that are then to be passed on to the slonik utility to be submitted to all of the Slony-I nodes in a particular cluster.  At one time, this embedded running slonik on the slonik scripts.  Unfortunately, this turned out to be a pretty large calibre "foot gun," as minor typos on the command line led, on a couple of occasions, to pretty calamitous actions, so the behaviour has been changed so that the scripts simply submit output to standard output.  An administrator should review the slonik script before submitting it to Slonik.
+
+<sect1><title> Node/Cluster Configuration - cluster.nodes</title>
+
+<para>The UNIX environment variable <envar/SLONYNODES/ is used to determine what Perl configuration file will be used to control the shape of the nodes in a Slony-I cluster.
+
+<para>What variables are set up...
+<itemizedlist>
+
+<listitem><Para> $SETNAME=orglogs;	# What is the name of the replication set?
+<listitem><Para> $LOGDIR='/opt/OXRS/log/LOGDBS';  # What is the base directory for logs?
+<listitem><Para> $SLON_BIN_PATH='/opt/dbs/pgsql74/bin';  # Where to look for slony binaries
+<listitem><Para> $APACHE_ROTATOR="/opt/twcsds004/OXRS/apache/rotatelogs";  # If set, where to find Apache log rotator
+</itemizedlist>
+
+<para>You then define the set of nodes that are to be replicated using a set of calls to <function/add_node()/.
+<para><command>
+  add_node (host => '10.20.30.40', dbname => 'orglogs', port => 5437,
+			  user => 'postgres', node => 4, parent => 1);
+</command></para>
+
+<para>The set of parameters for <function/add_node()/ are thus:
+<command>
+  my %PARAMS = (host=> undef,						# Host name
+		dbname => 'template1',			# database name
+		port => 5432,						# Port number
+		user => 'postgres',				# user to connect as
+		node => undef,					  # node number
+		password => undef,				 # password for user
+		parent => 1,						 # which node is parent to this node
+		noforward => undef				 # shall this node be set up to forward results?
+			 );
+</command>
+<sect1><title> Set configuration - cluster.set1, cluster.set2</title>
+
+<para>The UNIX environment variable <envar/SLONYSET/ is used to determine what Perl configuration file will be used to determine what objects will be contained in a particular replication set.
+
+<para>Unlike <envar/SLONYNODES/, which is essential for <emphasis/all/ of the slonik-generating scripts, this only needs to be set when running <filename/create_set.pl/, as that is the only script used to control what tables will be in a particular replication set.
+
+<para>What variables are set up...
+<itemizedlist>
+<listitem><Para> $TABLE_ID = 44;	 Each table must be identified by a unique number; this variable controls where numbering starts
+<listitem><Para> @PKEYEDTABLES		An array of names of tables to be replicated that have a defined primary key so that Slony-I can automatically select its key
+<listitem><Para> %KEYEDTABLES		 A hash table of tables to be replicated, where the hash index is the table name, and the hash value is the name of a unique not null index suitable as a "candidate primary key."
+<listitem><Para> @SERIALTABLES		An array of names of tables to be replicated that have no candidate for primary key.  Slony-I will add a key field based on a sequence that Slony-I generates
+<listitem><Para> @SEQUENCES			An array of names of sequences that are to be replicated
+</itemizedlist>
+
+<sect1><title/ build_env.pl/
+
+<para>Queries a database, generating output hopefully suitable for
+<filename/slon.env/ consisting of:
+<itemizedlist>
+
+<listitem><Para> a set of <function/add_node()/ calls to configure the cluster
+<listitem><Para> The arrays <envar/@KEYEDTABLES/, <envar/@SERIALTABLES/, and <envar/@SEQUENCES/
+</itemizedlist>
+
+<sect1><title/ create_set.pl/
+
+<para>This requires <envar/SLONYSET/ to be set as well as <envar/SLONYNODES/; it is used to
+generate the Slonik script to set up a replication set consisting of a
+set of tables and sequences that are to be replicated.
+
+<sect1><title/ drop_node.pl/
+
+<para>Generates Slonik script to drop a node from a Slony-I cluster.
+
+<sect1><title/ drop_set.pl/
+
+<para>Generates Slonik script to drop a replication set (<emphasis/e.g./ - set of tables and sequences) from a Slony-I cluster.
+
+<sect1><title/ failover.pl/
+
+<para>Generates Slonik script to request failover from a dead node to some new origin
+
+<sect1><title/ init_cluster.pl/
+
+<para>Generates Slonik script to initialize a whole Slony-I cluster,
+including setting up the nodes, communications paths, and the listener
+routing.
+
+<sect1><title/ merge_sets.pl/
+
+<para>Generates Slonik script to merge two replication sets together.
+
+<sect1><title/ move_set.pl/
+
+<para>Generates Slonik script to move the origin of a particular set to a different node.
+
+<sect1><title/ replication_test.pl/
+
+<para>Script to test whether Slony-I is successfully replicating data.
+
+<sect1><title/ restart_node.pl/
+
+<para>Generates Slonik script to request the restart of a node.  This was
+particularly useful pre-1.0.5 when nodes could get snarled up when
+slon daemons died.
+
+<sect1><title/ restart_nodes.pl/
+
+<para>Generates Slonik script to restart all nodes in the cluster.  Not
+particularly useful...
+
+<sect1><title/ show_configuration.pl/
+
+<para>Displays an overview of how the environment (e.g. - <envar/SLONYNODES/) is set
+to configure things.
+
+<sect1><title/ slon_kill.pl/
+
+<para>Kills slony watchdog and all slon daemons for the specified set.  It
+only works if those processes are running on the local host, of
+course!
+
+<sect1><title/ slon_pushsql.pl/
+
+<para>Generates Slonik script to push DDL changes to a replication set.
+
+<sect1><title/ slon_start.pl/
+
+<para>This starts a slon daemon for the specified cluster and node, and uses
+slon_watchdog.pl to keep it running.
+
+<sect1><title/ slon_watchdog.pl/
+
+<para>Used by slon_start.pl...
+
+<sect1><title/ slon_watchdog2.pl/
+
+<para>This is a somewhat smarter watchdog; it monitors a particular Slony-I
+node, and restarts the slon process if it hasn't seen updates go in in
+20 minutes or more.
+
+<para>This is helpful if there is an unreliable network connection such that
+the slon sometimes stops working without becoming aware of it...
+
+<sect1><title/ subscribe_set.pl/
+
+<para>Generates Slonik script to subscribe a particular node to a particular replication set.
+
+<sect1><title/ uninstall_nodes.pl/
+
+<para>This goes through and drops the Slony-I schema from each node; use
+this if you want to destroy replication throughout a cluster.  This is
+a VERY unsafe script!
+
+<sect1><title/ unsubscribe_set.pl/
+
+<para>Generates Slonik script to unsubscribe a node from a replication set.
+
+<sect1><title/ update_nodes.pl/
+
+<para>Generates Slonik script to tell all the nodes to update the Slony-I
+functions.  This will typically be needed when you upgrade from one
+version of Slony-I to another.
+
+
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/help.sgml
@@ -0,0 +1,37 @@
+<article id="help"> <title/ More Slony-I Help /
+<para>If you are having problems with Slony-I, you have several options for help:
+<itemizedlist>
+<listitem><Para> <ulink url="http://slony.info/">http://slony.info/</ulink> - the official "home" of Slony
+<listitem><Para> Documentation on the Slony-I Site- Check the documentation on the Slony website: <ulink url="http://gborg.postgresql.org/project/slony1/genpage.php?howto_idx">Howto </ulink>
+<listitem><Para> Other Documentation - There are several articles here <ulink url="http://www.varlena.com/varlena/GeneralBits/Tidbits/index.php#Replication"> Varlena GeneralBits </ulink> that may be helpful.
+<listitem><Para> IRC - There are usually some people on #slony on irc.freenode.net who may be able to answer some of your questions. There is also a bot named "rtfm_please" that you may want to chat with.
+<listitem><Para> Mailing lists - The answer to your problem may exist in the Slony1-general mailing list archives, or you may choose to ask your question on the Slony1-general mailing list. The mailing list archives, and instructions for joining the list may be found <ulink url="http://gborg.postgresql.org/mailman/listinfo/slony1">here. </ulink>
+
+<listitem><Para> If your Russian is much better than your English, then <ulink url="http://kirov.lug.ru/wiki/Slony"> KirovOpenSourceCommunity:  Slony</ulink>may be the place to go
+</itemizedlist>
+
+<sect1><title/ Other Information Sources/
+<itemizedlist>
+
+<listitem><Para> <ulink url="http://comstar.dotgeek.org/postgres/slony-config/"> slony-config</ulink>  - A Perl tool for configuring Slony nodes using config files in an XML-based format that the tool transforms into a Slonik script
+
+</itemizedlist>
+
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/cluster.sgml
@@ -0,0 +1,37 @@
+<article id="cluster"> <title/Defining Slony-I Clusters/
+
+<para>A Slony-I cluster is the basic grouping of database instances in
+which replication takes place.  It consists of a set of PostgreSQL
+database instances in which is defined a namespace specific to that
+cluster.
+
+<para>Each database instance in which replication is to take place is
+identified by a node number.
+
+<para>For a simple install, it may be reasonable for the "master" to
+be node #1, and for the "slave" to be node #2.
+
+<para>Some planning should be done, in more complex cases, to ensure that the numbering system is kept sane, lest the administrators be driven insane.  The node numbers should be chosen to somehow correspond to the shape of the environment, as opposed to (say) the order in which nodes were initialized.
+
+<para>It may be that in version 1.1, nodes will also have a "name"
+attribute, so that they may be given more mnemonic names.  In that
+case, the node numbers can be cryptic; it will be the node name that
+is used to organize the cluster.
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/filelist.sgml
@@ -0,0 +1,44 @@
+<!-- $PostgreSQL: pgsql/doc/src/sgml/filelist.sgml,v 1.40 2004/12/03 05:50:18 momjian Exp $ -->
+
+<!entity intro              SYSTEM "intro.sgml">
+<!entity prerequisites      SYSTEM "prerequisites.sgml">
+<!entity installation       SYSTEM "installation.sgml">
+<!entity slonik              SYSTEM "slonik.sgml">
+<!entity concepts           SYSTEM "concepts.sgml">
+<!entity cluster           SYSTEM "cluster.sgml">
+<!entity defineset           SYSTEM "defineset.sgml">
+<!entity adminscripts           SYSTEM "adminscripts.sgml">
+<!entity startslons           SYSTEM "startslons.sgml">
+<!entity slonconfig           SYSTEM "slonconfig.sgml">
+<!entity subscribenodes           SYSTEM "subscribenodes.sgml">
+<!entity monitoring           SYSTEM "monitoring.sgml">
+<!entity maintenance           SYSTEM "maintenance.sgml">
+<!entity reshape           SYSTEM "reshape.sgml">
+<!entity failover           SYSTEM "failover.sgml">
+<!entity listenpaths           SYSTEM "listenpaths.sgml">
+<!entity addthings           SYSTEM "addthings.sgml">
+<!entity dropthings           SYSTEM "dropthings.sgml">
+<!entity ddlchanges           SYSTEM "ddlchanges.sgml">
+<!entity firstdb           SYSTEM "firstdb.sgml">
+<!entity help           SYSTEM "help.sgml">
+
+
+
+<!entity history    SYSTEM "history.sgml">
+<!entity legal      SYSTEM "legal.sgml">
+<!entity notation   SYSTEM "notation.sgml">
+<!entity problems   SYSTEM "problems.sgml">
+
+
+<!-- back matter -->
+<!entity biblio     SYSTEM "biblio.sgml">
+<!entity bookindex  SYSTEM "bookindex.sgml">
+
+<!--
+ Some parts of the documentation are also source for some plain-text
+ files used during installation.  To selectively ignore or include
+ some parts (e.g., external xref's) when generating these files we use
+ these parameter entities.  See also standalone-install.sgml.
+ -->
+<!entity % standalone-ignore  "INCLUDE">
+<!entity % standalone-include "IGNORE">
--- /dev/null
+++ doc/adminguide/concepts.sgml
@@ -0,0 +1,79 @@
+<article id="concepts"> <title/Slony-I Concepts/
+
+
+<para>In order to set up a set of Slony-I replicas, it is necessary to understand the following major abstractions that it uses:
+
+<itemizedlist>
+	<listitem><Para> Cluster
+	<listitem><Para> Node
+	<listitem><Para> Replication Set
+	<listitem><Para> Provider and Subscriber
+</itemizedlist>
+
+<sect1><title/Cluster/
+
+<para>In Slony-I terms, a Cluster is a named set of PostgreSQL database instances; replication takes place between those databases.
+
+<para>The cluster name is specified in each and every Slonik script via the directive:
+<command>
+cluster name = 'something';
+</command>
+
+<para>If the Cluster name is 'something', then Slony-I will create, in each database instance in the cluster, the namespace/schema '_something'.
+
+<sect1><title/ Node/
+
+<para>A Slony-I Node is a named PostgreSQL database that will be participating in replication.  
+
+<para>It is defined, near the beginning of each Slonik script, using the directive:
+<command>
+ NODE 1 ADMIN CONNINFO = 'dbname=testdb host=server1 user=slony';
+</command>
+
+<para>The CONNINFO information indicates a string argument that will ultimately be passed to the <function/PQconnectdb()/ libpq function. 
+
+<para>Thus, a Slony-I cluster consists of:
+<itemizedlist>
+	<listitem><para> A cluster name
+	<listitem><Para> A set of Slony-I nodes, each of which has a namespace based on that cluster name
+</itemizedlist>
+
+<sect1><title/ Replication Set/
+
+<para>A replication set is defined as a set of tables and sequences that are to be replicated between nodes in a Slony-I cluster.
+
+<para>You may have several sets, and the "flow" of replication does not need to be identical between those sets.
+
+<sect1><title/ Provider and Subscriber/
+
+<para>Each replication set has some "master" node, which winds up
+being the <emphasis/only/ place where user applications are permitted
+to modify data in the tables that are being replicated.  That "master"
+may be considered the master "provider node;" it is the main place
+from which data is provided.
+
+<para>Other nodes in the cluster will subscribe to the replication
+set, indicating that they want to receive the data.
+
+<para>The "master" node will never be considered a "subscriber."  But
+Slony-I supports the notion of cascaded subscriptions, that is, a node
+that is subscribed to the "master" may also behave as a "provider" to
+other nodes in the cluster.
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/maintenance.sgml
@@ -0,0 +1,59 @@
+<article id="maintenance"> <title/Slony-I Maintenance/
+
+<para>Slony-I actually does most of its necessary maintenance itself, in a "cleanup" thread:
+<itemizedlist>
+	<Listitem><para> Deletes old data from various tables in the Slony-I cluster's namespace, notably entries in sl_log_1, sl_log_2 (not yet used), and sl_seqlog.
+
+	<listitem><Para> Vacuum certain tables used by Slony-I.  As of 1.0.5, this includes pg_listener; in earlier versions, you must vacuum that table heavily, otherwise you'll find replication slowing down because Slony-I raises plenty of events, which leads to that table having plenty of dead tuples.
+
+	<para> In some versions (1.1, for sure; possibly 1.0.5) there is the option of not bothering to vacuum any of these tables if you are using something like pg_autovacuum to handle vacuuming of these tables.  Unfortunately, it has been quite possible for pg_autovacuum to not vacuum quite frequently enough, so you probably want to use the internal vacuums.  Vacuuming pg_listener "too often" isn't nearly as hazardous as not vacuuming it frequently enough.
+
+	<para>Unfortunately, if you have long-running transactions, vacuums cannot clear out dead tuples that are newer than the eldest transaction that is still running.  This will most notably lead to pg_listener growing large and will slow replication.
+
+</itemizedlist>
+<sect1><title/ Watchdogs: Keeping Slons Running/
+
+<para>There are a couple of "watchdog" scripts available that monitor things, and restart the slon processes should they happen to die for some reason, such as a network "glitch" that causes loss of connectivity.
+
+<para>You might want to run them...
+
+<sect1><title/Alternative to Watchdog: generate_syncs.sh/
+
+<para>A new script for Slony-I 1.1 is "generate_syncs.sh", which addresses the following kind of situation.
+
+<para>Supposing you have some possibly-flakey slon daemon that might not run all the time, you might return from a weekend away only to discover the following situation...
+
+<para>On Friday night, something went "bump" and while the database came back up, none of the slon daemons survived.  Your online application then saw nearly three days worth of heavy transactions.
+
+<para>When you restart slon on Monday, it hasn't done a SYNC on the master since Friday, so that the next "SYNC set" comprises all of the updates between Friday and Monday.  Yuck.
+
+<para>If you run generate_syncs.sh as a cron job every 20 minutes, it will force in a periodic SYNC on the "master" server, which means that between Friday and Monday, the numerous updates are split into more than 100 syncs, which can be applied incrementally, making the cleanup a lot less unpleasant.
+
+<para>Note that if SYNCs <emphasis/are/ running regularly, this script won't bother doing anything.
+
+<sect1><title/ Log Files/
+
+<para>Slon daemons generate some more-or-less verbose log files, depending on what debugging level is turned on.  You might assortedly wish to:
+<itemizedlist>
+	<listitem><Para> Use a log rotator like Apache rotatelogs to have a sequence of log files so that no one of them gets too big;
+
+	<listitem><Para> Purge out old log files, periodically.
+</itemizedlist>
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
+
--- /dev/null
+++ doc/adminguide/slonconfig.sgml
@@ -0,0 +1,84 @@
+<article id="slonconfig"> <title/Slon Configuration Options/
+
+<para>Slon parameters:
+
+<para> usage: slon [options] clustername conninfo
+
+<para>
+<command>
+Options:
+-d debuglevel		 verbosity of logging (1..8)
+-s milliseconds	  SYNC check interval (default 10000)
+-t milliseconds	  SYNC interval timeout (default 60000)
+-g num				  maximum SYNC group size (default 6)
+-c num				  how often to vacuum in cleanup cycles
+-p filename			slon pid file
+-f filename			slon configuration file
+</command>
+
+<itemizedlist>
+
+<listitem><para><option/-d/
+
+<para>The eight levels of logging are:
+<itemizedlist>
+<listitem><Para>Error
+<listitem><Para>Warn
+<listitem><Para>Config
+<listitem><Para>Info
+<listitem><Para>Debug1
+<listitem><Para>Debug2
+<listitem><Para>Debug3
+<listitem><Para>Debug4
+</itemizedlist>
+		  
+<listitem><para><option/-s/
+
+<para>A SYNC event will be sent at least this often, regardless of whether update activity is detected.
+
+<para>Short sync times keep the master on a "short leash," updating the slaves more frequently.  If you have replicated sequences that are frequently updated _without_ there being tables that are affected, this keeps there from being times when only sequences are updated, and therefore <emphasis/no/ syncs take place.
+
+<para>Longer sync times allow there to be fewer events, which allows somewhat better efficiency.
+
+<listitem><para><option/-t/
+
+<para>The time before the SYNC check interval times out.
+
+<listitem><para><option/-g/
+
+<para>Number of SYNC events to try to cram together.  The default is 6, which is probably suitable for small systems that can devote only very limited bits of memory to slon.  If you have plenty of memory, it would be reasonable to increase this, as it will increase the amount of work done in each transaction, and will allow a subscriber that is behind by a lot to catch up more quickly.
+
+<para>Slon processes usually stay pretty small; even with large value for this option, slon would be expected to only grow to a few MB in size.
+
+<listitem><para><option/-c/
+
+<para>How often to vacuum (<emphasis/e.g./ - how many cleanup cycles to run before vacuuming). 
+
+<para>Set this to zero to disable slon-initiated vacuuming.  If you are using something like <application/pg_autovacuum/ to initiate vacuums, you may not need for slon to initiate vacuums itself.  If you are not, there are some tables Slony-I uses that collect a <emphasis/lot/ of dead tuples that should be vacuumed frequently.
+
+<listitem><para><option/-p/
+
+<para> The location of the PID file for the slon process.
+
+<listitem><para><option/-f/
+
+<para>The location of the slon configuration file.
+</itemizedlist>
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/firstdb.sgml
@@ -0,0 +1,296 @@
+<article id="firstdb"><title/Replicating Your First Database/
+
+<para>In this example, we will be replicating a brand new pgbench database.  The
+mechanics of replicating an existing database are covered here, however we
+recommend that you learn how Slony-I functions by using a fresh new
+non-production database.
+
+<para>The Slony-I replication engine is trigger-based, allowing us to replicate
+databases (or portions thereof) running under the same postmaster.
+
+<para>This example will show how to replicate the pgbench database running on
+localhost (master) to the pgbench slave database also running on localhost
+(slave).  We make a couple of assumptions about your PostgreSQL configuration:
+<itemizedlist>
+	<listitem><para> You have tcpip_socket=true in your postgresql.conf and
+	<listitem><para> You have enabled access in your cluster(s) via pg_hba.conf
+</itemizedlist>
+
+<para> The REPLICATIONUSER needs to be a PostgreSQL superuser.  This is typically
+postgres or pgsql.
+
+<para>You should also set the following shell variables:
+
+<itemizedlist>
+<listitem><para> <envar/CLUSTERNAME/=slony_example
+<listitem><para> <envar/MASTERDBNAME/=pgbench
+<listitem><para> <envar/SLAVEDBNAME/=pgbenchslave
+<listitem><para> <envar/MASTERHOST/=localhost
+<listitem><para> <envar/SLAVEHOST/=localhost
+<listitem><para> <envar/REPLICATIONUSER/=pgsql
+<listitem><para> <envar/PGBENCHUSER/=pgbench
+</itemizedlist>
+<para>Here are a couple of examples for setting variables in common shells:
+
+<itemizedlist>
+<listitem><Para> bash, sh, ksh
+	<command/export CLUSTERNAME=slony_example/
+<listitem><Para> (t)csh:
+	<command/setenv CLUSTERNAME slony_example/
+</itemizedlist>
+
+<para><warning><Para> If you're changing these variables to use different
+hosts for MASTERHOST and SLAVEHOST, be sure <emphasis/not/ to use
+localhost for either of them.  This will result in an error similar to
+the following:
+
+<para><command>
+ERROR  remoteListenThread_1: db_getLocalNodeId() returned 2 - wrong database?
+</command>
+</warning></para>
+
+<sect1><title/ Creating the pgbenchuser/
+
+<para><command>
+createuser -A -D $PGBENCHUSER
+</command>
+
+<sect1><title/ Preparing the databases/
+
+<para><command>
+createdb -O $PGBENCHUSER -h $MASTERHOST $MASTERDBNAME
+createdb -O $PGBENCHUSER -h $SLAVEHOST $SLAVEDBNAME
+pgbench -i -s 1 -U $PGBENCHUSER -h $MASTERHOST $MASTERDBNAME
+</command>
+
+<para>Because Slony-I depends on the databases having the pl/pgSQL procedural
+language installed, we better install it now.  It is possible that you have
+installed pl/pgSQL into the template1 database in which case you can skip this
+step because it's already installed into the $MASTERDBNAME.
+
+<command>
+createlang plpgsql -h $MASTERHOST $MASTERDBNAME
+</command>
+
+<para>Slony-I does not yet automatically copy table definitions from a master when a
+slave subscribes to it, so we need to import this data.  We do this with
+pg_dump.
+
+<para><command>
+pg_dump -s -U $REPLICATIONUSER -h $MASTERHOST $MASTERDBNAME | psql -U $REPLICATIONUSER -h $SLAVEHOST $SLAVEDBNAME
+</command>
+
+<para>To illustrate how Slony-I allows for on the fly replication subscription, lets
+start up pgbench.  If you run the pgbench application in the foreground of a
+separate terminal window, you can stop and restart it with different
+parameters at any time.  You'll need to re-export the variables again so they
+are available in this session as well.
+
+<para>The typical command to run pgbench would look like:
+
+<para><command>
+pgbench -s 1 -c 5 -t 1000 -U $PGBENCHUSER -h $MASTERHOST $MASTERDBNAME
+</command>
+
+<para>This will run pgbench with 5 concurrent clients each processing 1000
+transactions against the pgbench database running on localhost as the pgbench
+user.
+
+<sect1><title/ Configuring the Database for Replication./
+
+<para>Creating the configuration tables, stored procedures, triggers and
+configuration is all done through the slonik tool.  It is a specialized
+scripting aid that mostly calls stored procedures in the master/salve (node)
+databases.  The script to create the initial configuration for the simple
+master-slave setup of our pgbench database looks like this:
+
+<para><command>
+#!/bin/sh
+
+slonik <<_EOF_
+	#--
+	 # define the namespace the replication system uses in our example it is
+	 # slony_example
+	#--
+	cluster name = $CLUSTERNAME;
+
+	#--
+	 # admin conninfo's are used by slonik to connect to the nodes one for each
+	 # node on each side of the cluster, the syntax is that of PQconnectdb in
+	 # the C-API
+	# --
+	node 1 admin conninfo = 'dbname=$MASTERDBNAME host=$MASTERHOST user=$REPLICATIONUSER';
+	node 2 admin conninfo = 'dbname=$SLAVEDBNAME host=$SLAVEHOST user=$REPLICATIONUSER';
+
+	#--
+	 # init the first node.  Its id MUST be 1.  This creates the schema
+	 # _$CLUSTERNAME containing all replication system specific database
+	 # objects.
+
+	#--
+	init cluster ( id=1, comment = 'Master Node');
+ 
+	#--
+	 # Because the history table does not have a primary key or other unique
+	 # constraint that could be used to identify a row, we need to add one.
+	 # The following command adds a bigint column named
+	 # _Slony-I_$CLUSTERNAME_rowID to the table.  It will have a default value
+	 # of nextval('_$CLUSTERNAME.s1_rowid_seq'), and have UNIQUE and NOT NULL
+	 # constraints applied.  All existing rows will be initialized with a
+	 # number
+	#--
+	table add key (node id = 1, fully qualified name = 'public.history');
+
+	#--
+	 # Slony-I organizes tables into sets.  The smallest unit a node can
+	 # subscribe is a set.  The following commands create one set containing
+	 # all 4 pgbench tables.  The master or origin of the set is node 1.
+	#--
+	create set (id=1, origin=1, comment='All pgbench tables');
+	set add table (set id=1, origin=1, id=1, fully qualified name = 'public.accounts', comment='accounts table');
+	set add table (set id=1, origin=1, id=2, fully qualified name = 'public.branches', comment='branches table');
+	set add table (set id=1, origin=1, id=3, fully qualified name = 'public.tellers', comment='tellers table');
+	set add table (set id=1, origin=1, id=4, fully qualified name = 'public.history', comment='history table', key = serial);
+
+	#--
+	 # Create the second node (the slave) tell the 2 nodes how to connect to
+	 # each other and how they should listen for events.
+	#--
+
+	store node (id=2, comment = 'Slave node');
+	store path (server = 1, client = 2, conninfo='dbname=$MASTERDBNAME host=$MASTERHOST user=$REPLICATIONUSER');
+	store path (server = 2, client = 1, conninfo='dbname=$SLAVEDBNAME host=$SLAVEHOST user=$REPLICATIONUSER');
+	store listen (origin=1, provider = 1, receiver =2);
+	store listen (origin=2, provider = 2, receiver =1);
+_EOF_
+</command>
+
+
+<para>Is the pgbench still running?  If not start it again.
+
+<para>At this point we have 2 databases that are fully prepared.  One is the master
+database in which bgbench is busy accessing and changing rows.  It's now time
+to start the replication daemons.
+
+<para>On $MASTERHOST the command to start the replication engine is
+
+<para><command>
+slon $CLUSTERNAME "dbname=$MASTERDBNAME user=$REPLICATIONUSER host=$MASTERHOST"
+</command>
+
+<para>Likewise we start the replication system on node 2 (the slave)
+
+<para><command>
+slon $CLUSTERNAME "dbname=$SLAVEDBNAME user=$REPLICATIONUSER host=$SLAVEHOST"
+</command>
+
+<para>Even though we have the slon running on both the master and slave and they are
+both spitting out diagnostics and other messages, we aren't replicating any
+data yet.  The notices you are seeing is the synchronization of cluster
+configurations between the 2 slon processes.
+
+<para>To start replicating the 4 pgbench tables (set 1) from the master (node id 1)
+the the slave (node id 2), execute the following script.
+
+<para><command>
+#!/bin/sh
+slonik <<_EOF_
+	 # ----
+	 # This defines which namespace the replication system uses
+	 # ----
+	 cluster name = $CLUSTERNAME;
+
+	 # ----
+	 # Admin conninfo's are used by the slonik program to connect
+	 # to the node databases.  So these are the PQconnectdb arguments
+	 # that connect from the administrators workstation (where
+	 # slonik is executed).
+	 # ----
+	 node 1 admin conninfo = 'dbname=$MASTERDBNAME host=$MASTERHOST user=$REPLICATIONUSER';
+	 node 2 admin conninfo = 'dbname=$SLAVEDBNAME host=$SLAVEHOST user=$REPLICATIONUSER';
+
+	 # ----
+	 # Node 2 subscribes set 1
+	 # ----
+	 subscribe set ( id = 1, provider = 1, receiver = 2, forward = no);
+_EOF_
+</command>
+
+<para>Any second here, the replication daemon on $SLAVEHOST will start to copy the
+current content of all 4 replicated tables.  While doing so, of course, the
+pgbench application will continue to modify the database.  When the copy
+process is finished, the replication daemon on $SLAVEHOST will start to catch
+up by applying the accumulated replication log.  It will do this in little
+steps, 10 seconds worth of application work at a time.  Depending on the
+performance of the two systems involved, the sizing of the two databases, the
+actual transaction load and how well the two databases are tuned and
+maintained, this catchup process can be a matter of minutes, hours, or
+eons.
+
+<para>You have now successfully set up your first basic master/slave replication
+system, and the 2 databases once the slave has caught up contain identical
+data.  That's the theory.  In practice, it's good to check that the datasets
+are in fact the same.
+
+<para>The following script will create ordered dumps of the 2 databases and compare
+them.  Make sure that pgbench has completed it's testing, and that your slon
+sessions have caught up.
+
+<para><command>
+#!/bin/sh
+echo -n "**** comparing sample1 ... "
+psql -U $REPLICATIONUSER -h $MASTERHOST $MASTERDBNAME >dump.tmp.1.$$ <<_EOF_
+	 select 'accounts:'::text, aid, bid, abalance, filler
+		  from accounts order by aid;
+	 select 'branches:'::text, bid, bbalance, filler
+		  from branches order by bid;
+	 select 'tellers:'::text, tid, bid, tbalance, filler
+		  from tellers order by tid;
+	 select 'history:'::text, tid, bid, aid, delta, mtime, filler,
+		  "_Slony-I_${CLUSTERNAME}_rowID"
+		  from history order by "_Slony-I_${CLUSTERNAME}_rowID";
+_EOF_
+psql -U $REPLICATIONUSER -h $SLAVEHOST $SLAVEDBNAME >dump.tmp.2.$$ <<_EOF_
+	 select 'accounts:'::text, aid, bid, abalance, filler
+		  from accounts order by aid;
+	 select 'branches:'::text, bid, bbalance, filler
+		  from branches order by bid;
+	 select 'tellers:'::text, tid, bid, tbalance, filler
+		  from tellers order by tid;
+	 select 'history:'::text, tid, bid, aid, delta, mtime, filler,
+		  "_Slony-I_${CLUSTERNAME}_rowID"
+		  from history order by "_Slony-I_${CLUSTERNAME}_rowID";
+_EOF_
+
+if diff dump.tmp.1.$$ dump.tmp.2.$$ >$CLUSTERNAME.diff ; then
+	 echo "success - databases are equal."
+	 rm dump.tmp.?.$$
+	 rm $CLUSTERNAME.diff
+else
+	 echo "FAILED - see $CLUSTERNAME.diff for database differences"
+fi
+</command>
+
+<para>Note that there is somewhat more sophisticated documentation of the process in the Slony-I source code tree in a file called slony-I-basic-mstr-slv.txt.
+
+<para>If this script returns "FAILED" please contact the developers at
+<ulink url="http://slony.org/"> http://slony.org/</ulink>
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
+
--- /dev/null
+++ doc/adminguide/prerequisites.sgml
@@ -0,0 +1,87 @@
+<sect1><title/ Requirements/
+
+<para>Any platform that can run PostgreSQL should be able to run Slony-I.  
+
+<para>The platforms that have received specific testing at the time of this release are
+FreeBSD-4X-i368, FreeBSD-5X-i386, FreeBSD-5X-alpha, osX-10.3, Linux-2.4X-i386
+Linux-2.6X-i386 Linux-2.6X-amd64, Solaris-2.8-SPARC, Solaris-2.9-SPARC, AIX 5.1 and
+OpenBSD-3.5-sparc64.
+
+<para>There have been reports of success at running Slony-I hosts that are running PostgreSQL on Microsoft Windows(tm).  At this time, the "binary" applications (e.g. - slonik, slon) do not run on Windows(tm), but a slon running on one of the Unix-like systems has no reason to have difficulty connect to a PostgreSQL instance running on Windows(tm).
+
+<para> It ought to be possible to port slon and slonik to run on Windows; the conspicuous challenge is of having a POSIX-like pthreads implementation for slon, as it uses that to have multiple threads of execution.  There are reports of there being a pthreads library for Windows(tm), so nothing should prevent some interested party from volunteering to do the port.
+
+<sect2><title/ Software needed/
+<para>
+<itemizedlist>
+	<listitem><Para> GNU make.  Other make programs will not work.  GNU make is often installed under the name gmake; this document will therefore always refer to it by that name. (On Linux-based systems GNU make is typically the default make, and is called "make")  To test to see if your make is GNU make enter "make version."  Version 3.76 or later will suffice; previous versions may not.
+
+	<listitem><Para> You need an ISO/ANSI C compiler.  Recent versions of GCC work.
+
+	<listitem><Para> You also need a recent version of PostgreSQL *source*.  Slony-I depends on namespace support so you must have version 7.3 or newer to be able to build and use Slony-I.  Rod Taylor has "hacked up" a version of Slony-I that works with version 7.2; if you desperately need that, look for him on the PostgreSQL Hackers mailing list.  It is not anticipated that 7.2 will be supported by any official Slony-I release.
+
+	<listitem><Para> GNU packages may be included in the standard packaging for your operating system, or you may need to look for source code at your local GNU mirror (see <ulink url="http://www.gnu.org/order/ftp.html"> http://www.gnu.org/order/ftp.html</ulink>  for a list) or at <ulink url="ftp://ftp.gnu.org/gnu"> ftp://ftp.gnu.org/gnu</ulink> .)
+
+	<listitem><Para> If you need to obtain PostgreSQL source, you can download it from your favorite PostgreSQL mirror (see <ulink url="http://www.postgresql.org/mirrors-www.html"> http://www.postgresql.org/mirrors-www.html </ulink>  for a list), or via <ulink url="http://bt.postgresql.org/"> BitTorrent</ulinK>.
+</itemizedlist>
+
+<para>Also check to make sure you have sufficient disk space.  You will need
+approximately 5MB for the source tree during build and installation.
+
+<sect2><title/ Getting Slony-I Source/
+
+<para>You can get the Slony-I source from <ulink
+url="http://developer.postgresql.org/~wieck/slony1/download/">
+http://developer.postgresql.org/~wieck/slony1/download/</ulinK>
+
+<sect2><title/ Time Synchronization/
+
+<para> All the servers used within the replication cluster need to have their Real Time Clocks in sync. This is to ensure that slon doesn't error with messages indicating that slave is already ahead of the master during replication.  We recommend you have ntpd running on all nodes, with subscriber nodes using the "master" provider node as their time server.
+
+<para> It is possible for Slony-I to function even in the face of there being some time discrepancies, but having systems "in sync" is usually pretty important for distributed applications.
+
+<Para> See <ulink url="http://www.ntp.org/"> www.ntp.org </ulink> for
+more details about NTP (Network Time Protocol).
+
+<sect2><title/ Network Connectivity/
+
+<para>It is necessary that the hosts that are to replicate between one another have <emphasis/bidirectional/ network communications to the PostgreSQL instances.  That is, if node B is replicating data from node A, it is necessary that there be a path from A to B and from B to A.  It is recommended that all nodes in a Slony-I cluster allow this sort of bidirection communications from any node in the cluster to any other node in the cluster.
+
+<para>Note that the network addresses need to be consistent across all
+of the nodes.  Thus, if there is any need to use a "public" address
+for a node, to allow remote/VPN access, that "public" address needs to
+be able to be used consistently throughout the Slony-I cluster, as the
+address is propagated throughout the cluster in table <envar/sl_path/.
+
+<para>A possible workaround for this, in environments where firewall
+rules are particularly difficult to implement, may be to establish
+SSHTunnels that are created on each host that allow remote access
+through IP address 127.0.0.1, with a different port for each
+destination.
+
+<para> Note that slonik and the slon instances need no special
+connections to communicate with one another; they just need to be able
+to get access to the PostgreSQL databases.
+
+<para> An implication of the communications model is that the extended
+network in which a Slony-I cluster operates must be able to be treated
+as being secure.  If there is a remote location where you cannot trust
+the Slony-I node to be considered "secured," this represents a
+vulnerability that affects <emphasis/all/ the nodes throughout the
+cluster.  In effect, the security policies throughout the cluster can
+only be considered as stringent as those applied at the
+<emphasis/weakest/ link.  Running a full-blown Slony-I node at a
+branch location that can't be kept secure compromises security for
+<emphasis/every node/ in the cluster.
+
+<para>In the future plans is a feature whereby updates for a
+particular replication set would be serialized via a scheme called
+"log shipping."  The data stored in sl_log_1 and sl_log_2 would be
+written out to log files on disk.  These files could be transmitted in
+any manner desired, whether via scp, FTP, burning them onto DVD-ROMs
+and mailing them, or even by recording them on a USB "flash device"
+and attaching them to birds, allowing a sort of "avian transmission
+protocol."  This will allow one way communications so that
+"subscribers" that use log shipping would have no need for access to
+other Slony-I nodes.
+
--- /dev/null
+++ doc/adminguide/stylesheet.xsl
@@ -0,0 +1,108 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version='1.0'
+                xmlns="http://www.w3.org/TR/xhtml1/transitional"
+                exclude-result-prefixes="#default">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/>
+
+<!-- Parameters -->
+
+<xsl:param name="pg.fast" select="'0'"/>
+
+<!--
+<xsl:param name="draft.mode">
+  <xsl:choose>
+    <xsl:when test="contains($pg.version, 'devel')">yes</xsl:when>
+    <xsl:otherwise>no</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+-->
+
+<xsl:param name="show.comments">
+  <xsl:choose>
+    <xsl:when test="contains($pg.version, 'devel')">1</xsl:when>
+    <xsl:otherwise>0</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+
+<xsl:param name="callout.graphics" select="'0'"></xsl:param>
+<xsl:param name="toc.section.depth">2</xsl:param>
+<xsl:param name="linenumbering.extension" select="'0'"></xsl:param>
+<xsl:param name="generate.index" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="preface.autolabel" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="section.autolabel" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="section.label.includes.component.label" select="1 - $pg.fast"></xsl:param>
+<xsl:param name="html.stylesheet" select="'stylesheet.css'"></xsl:param>
+<xsl:param name="use.id.as.filename" select="'1'"></xsl:param>
+<xsl:param name="make.valid.html" select="1"></xsl:param>
+<xsl:param name="generate.id.attributes" select="1"></xsl:param>
+<xsl:param name="generate.legalnotice.link" select="1"></xsl:param>
+<xsl:param name="refentry.xref.manvolnum" select="0"/>
+<xsl:param name="link.mailto.url">pgsql-docs at postgresql.org</xsl:param>
+<xsl:param name="formal.procedures" select="0"></xsl:param>
+<xsl:param name="punct.honorific" select="''"></xsl:param>
+<xsl:param name="chunker.output.indent" select="'yes'"/>
+<xsl:param name="chunk.quietly" select="1"></xsl:param>
+
+
+<!-- Change display of some elements -->
+
+<xsl:template match="command">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="productname">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="structfield">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="structname">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="symbol">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="systemitem">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="token">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="type">
+  <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="programlisting/emphasis">
+  <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+
+<!-- Special support for Tcl synopses -->
+
+<xsl:template match="optional[@role='tcl']">
+  ?<xsl:call-template name="inline.charseq"/>?
+</xsl:template>
+
+
+<!--
+  Format multiple terms in varlistentry vertically, instead
+  of comma-separated.
+ -->
+
+<xsl:template match="varlistentry/term[position()!=last()]">
+  <span class="term">
+    <xsl:call-template name="anchor"/>
+    <xsl:apply-templates/>
+  </span><br/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+++ doc/adminguide/subscribenodes.sgml
@@ -0,0 +1,71 @@
+<article id="subscribenodes"> <title/ Subscribing Nodes/
+
+<para>Before you subscribe a node to a set, be sure that you have slons running for both the master and the new subscribing node. If you don't have slons running, nothing will happen, and you'll beat your head against a wall trying to figure out what's going on.
+
+<para>Subscribing a node to a set is done by issuing the slonik command "subscribe set". It may seem tempting to try to subscribe several nodes to a set within the same try block like this:
+
+<para> <command>
+try {
+		  echo 'Subscribing sets';
+		  subscribe set (id = 1, provider=1, receiver=2, forward=yes);
+		  subscribe set (id = 1, provider=1, receiver=3, forward=yes);
+		  subscribe set (id = 1, provider=1, receiver=4, forward=yes);
+} on error {
+		  echo 'Could not subscribe the sets!';
+		  exit -1;
+}
+</command>
+
+<para> You are just asking for trouble if you try to subscribe sets like that. The proper procedure is to subscribe one node at a time, and to check the logs and databases before you move onto subscribing the next node to the set. It is also worth noting that success within the above slonik try block does not imply that nodes 2, 3, and 4 have all been successfully subscribed. It merely guarantees that the slonik commands were received by the slon running on the master node.
+
+<para>A typical sort of problem that will arise is that a cascaded
+subscriber is looking for a provider that is not ready yet.  In that
+failure case, that subscriber node will <emphasis/never/ pick up the
+subscriber.  It will get "stuck" waiting for a past event to take
+place.  The other nodes will be convinced that it is successfully
+subscribed (because no error report ever made it back to them); a
+request to unsubscribe the node will be "blocked" because the node is
+stuck on the attempt to subscribe it.
+
+<para>When you subscribe a node to a set, you should see something like this in your slony logs for the master node:
+
+<para> <command>
+DEBUG2 remoteWorkerThread_3: Received event 3,1059 SUBSCRIBE_SET
+</command>
+
+<para>You should also start seeing log entries like this in the slony logs for the subscribing node:
+
+<para><command>
+DEBUG2 remoteWorkerThread_1: copy table public.my_table
+</command>
+
+<para>It may take some time for larger tables to be copied from the master node to the new subscriber. If you check the pg_stat_activity table on the master node, you should see a query that is copying the table to stdout.
+
+<para>The table sl_subscribe on both the master, and the new subscriber should have entries for the new subscription:
+
+<para><Command>
+ sub_set | sub_provider | sub_receiver | sub_forward | sub_active
+---------+--------------+--------------+-------------+------------
+	1	  |				1 |				2 | t			  | t
+</command>
+
+<para>A final test is to insert a row into a table on the master node, and to see if the row is copied to the new subscriber. 
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
+
--- /dev/null
+++ doc/adminguide/legal.sgml
@@ -0,0 +1,61 @@
+<!--
+$Id: legal.sgml,v 1.1 2004/12/06 23:44:54 cbbrowne Exp $
+-->
+
+<copyright>
+ <year>2004-2005</year>
+ <holder>The PostgreSQL Global Development Group</holder>
+</copyright>
+
+<legalnotice id="legalnotice">
+ <title>Legal Notice</title>
+
+ <para>
+  <productname>PostgreSQL</productname> is Copyright &copy; 2004-2005
+  by the PostgreSQL Global Development Group and is distributed under
+  the terms of the license of the University of California below.
+ </para>
+
+ <para>
+  Permission to use, copy, modify, and distribute this software and
+  its documentation for any purpose, without fee, and without a
+  written agreement is hereby granted, provided that the above
+  copyright notice and this paragraph and the following two paragraphs
+  appear in all copies.
+ </para>
+
+ <para>
+  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY
+  PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+  DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS
+  SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA
+  HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ </para>
+
+ <para>
+  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
+  PROVIDED HEREUNDER IS ON AN <quote>AS-IS</quote> BASIS, AND THE
+  UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
+  SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ </para>
+
+</legalnotice>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/Makefile
@@ -0,0 +1,227 @@
+#----------------------------------------------------------------------------
+#
+# PostgreSQL documentation makefile
+#
+# $Id: Makefile,v 1.1 2004/12/06 23:44:53 cbbrowne Exp $
+#
+#----------------------------------------------------------------------------
+
+subdir = doc/adminguide
+top_builddir = ../..
+
+.SECONDARY:
+.NOTPARALLEL:
+
+ifndef COLLATEINDEX
+COLLATEINDEX = /usr/bin/collateindex.pl
+endif
+
+ifndef JADE
+JADE = jade
+endif
+SGMLINCLUDE = -D $(srcdir)
+
+# If this is a vpath build, some generated SGML will be in the build
+# tree, so we need to make sure we look there as well as in the
+# source tree
+ifeq ($(vpath_build), yes)
+SGMLINCLUDE += -D .
+endif
+
+ifndef NSGMLS
+NSGMLS = nsgmls
+endif
+
+ifndef SGMLSPL
+SGMLSPL = sgmlspl
+endif
+
+CONVERT = convert
+EPSTOPDF = epstopdf
+
+# docbook2man generates man pages from docbook refentry source code.
+D2MSCRIPT= $(D2MDIR)/docbook2man-spec.pl
+
+
+GENERATED_SGML = bookindex.sgml 
+
+ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML)
+
+ifdef DOCBOOKSTYLE
+CATALOG = -c $(DOCBOOKSTYLE)/catalog
+endif
+
+# Enable draft mode during development
+ifneq (,$(findstring devel, $(VERSION)))
+override JADEFLAGS += -V draft-mode
+endif
+
+# Enable some extra warnings
+override SPFLAGS += -wall -wno-unused-param -wno-empty
+
+##
+## Man pages
+##
+
+.PHONY: man
+
+DEFAULTSECTION := $(sqlmansect_dummy)
+
+man: slony.sgml $(ALLSGML)
+	$(NSGMLS) $(NSGMLS_FLAGS) $< | $(SGMLSPL) $(D2MSCRIPT) --lowercase --section $(DEFAULTSECTION) --date "`date '+%Y-%m-%d'`"
+# One more time, to resolve cross-references
+	$(NSGMLS) $(NSGMLS_FLAGS) $< | $(SGMLSPL) $(D2MSCRIPT) --lowercase --section $(DEFAULTSECTION) --date "`date '+%Y-%m-%d'`"
+	mkdir -p man1 man$(DEFAULTSECTION)
+	mv *.1 man1/
+	mv *.$(DEFAULTSECTION) man$(DEFAULTSECTION)/
+
+
+##
+## HTML
+##
+
+all: html
+
+.PHONY: html
+
+html: slony.sgml $(ALLSGML) stylesheet.dsl
+	@rm -f *.html
+	$(JADE) $(JADEFLAGS) $(SPFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -ioutput-html -t sgml $<
+ifeq ($(vpath_build), yes)
+	@cp $(srcdir)/stylesheet.css .
+endif
+
+
+COLLATEINDEX := LC_ALL=C $(PERL) $(COLLATEINDEX) -f -g
+
+ifeq (,$(wildcard HTML.index))
+bookindex.sgml:
+	$(COLLATEINDEX) -o $@ -N
+else
+bookindex.sgml: HTML.index
+	$(COLLATEINDEX) -i 'bookindex' -o $@ $<
+endif
+
+##
+## Print
+##
+
+# RTF to allow minor editing for hardcopy
+
+%.rtf: %.sgml $(ALLSGML) stylesheet.dsl
+	$(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t rtf -V rtf-backend -ioutput-print $<
+
+# TeX
+# Regular TeX and pdfTeX have slightly differing requirements, so we
+# need to distinguish the path we're taking.
+
+%.tex-ps: %.sgml $(ALLSGML) stylesheet.dsl
+	$(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t tex -V tex-backend -ioutput-print -V texdvi-output -o $@ $<
+
+%.tex-pdf: %.sgml $(ALLSGML) stylesheet.dsl
+	$(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t tex -V tex-backend -ioutput-print -V texpdf-output -o $@ $<
+
+%.dvi: %.tex-ps
+	@rm -f $*.aux $*.log
+	jadetex $<
+	jadetex $<
+	jadetex $<
+
+# Postscript from TeX
+%.ps: %.dvi
+	dvips -o $@ $<
+
+%.pdf: %.tex-pdf
+	@rm -f $*.aux $*.log $*.out
+	pdfjadetex $<
+	pdfjadetex $<
+	pdfjadetex $<
+
+
+# This generates an XML version of the flow-object tree.  It's useful
+# for debugging DSSSL code, and possibly to interface to some other
+# tools that can make use of this.
+%.fot: %.sgml $(ALLSGML) stylesheet.dsl
+	$(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t fot -i output-print -o $@ $<
+
+
+# Graphics
+
+%.gif:
+	cp $(srcdir)/../graphics/$@ .
+
+%.eps: %.gif
+	$(CONVERT) $< eps:$@
+
+%.pdf: %.eps
+	$(EPSTOPDF) $<
+
+
+##
+## Semi-automatic generation of some text files.
+##
+
+JADE.text = $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -i output-text -t sgml
+LYNX = lynx
+
+INSTALL HISTORY regress_README: % : %.html
+	$(PERL) -p -e 's/<H(1|2)$$/<H\1 align=center/g' $< | $(LYNX) -force_html -dump -nolist -stdin >$@
+
+INSTALL.html: standalone-install.sgml installation.sgml 
+	$(JADE.text) -V nochunks standalone-install.sgml installation.sgml >$@
+
+HISTORY.html: release.sgml
+	( echo '<!doctype appendix PUBLIC "-//OASIS//DTD DocBook V4.2//EN">'; \
+	  cat $< ) >tempfile_HISTORY.sgml
+	$(JADE.text) -V nochunks tempfile_HISTORY.sgml >$@
+	rm tempfile_HISTORY.sgml
+
+regress_README.html: regress.sgml
+	( echo '<!doctype chapter PUBLIC "-//OASIS//DTD DocBook V4.2//EN" ['; \
+	  echo '<!entity % standalone-ignore "IGNORE"> ]>'; \
+	  cat $< ) >tempfile_regress_README.sgml
+	$(JADE.text) -V nochunks tempfile_regress_README.sgml >$@
+	rm tempfile_regress_README.sgml
+
+
+##
+## Experimental XML stuff
+##
+
+OSX = osx # (may be called sx or sgml2xml on some systems)
+XSLTPROC = xsltproc
+
+postgres.xml: postgres.sgml $(GENERATED_SGML)
+	$(OSX) -x lower $< | \
+	  sed -e 's/\[\(lt\|gt\|amp\|nbsp\|copy\|quot\|ouml\|uuml\|egrave\) *\]/\&\1;/g' \
+	      -e '1a\' -e '<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">' \
+	  >$@
+
+testxml: stylesheet.xsl postgres.xml
+	$(XSLTPROC) $(XSLTPROCFLAGS) --stringparam pg.version '$(VERSION)' $^
+
+
+##
+## Check
+##
+
+# Quick syntax check without style processing
+check: postgres.sgml $(ALLSGML)
+	$(NSGMLS) $(SPFLAGS) $(SGMLINCLUDE) -s $<
+
+
+##
+## Clean
+##
+
+clean distclean maintainer-clean:
+# HTML
+	rm -f HTML.manifest *.html *.gif
+# man
+	rm -rf *.1 *.$(DEFAULTSECTION) man1 man$(DEFAULTSECTION) manpage.refs manpage.links manpage.log
+# print
+	rm -f *.rtf *.tex-ps *.tex-pdf *.dvi *.aux *.log *.ps *.pdf *.out *.eps *.fot
+# index
+	rm -f HTML.index $(GENERATED_SGML)
+# text
+	rm -f INSTALL HISTORY regress_README
--- /dev/null
+++ doc/adminguide/reshape.sgml
@@ -0,0 +1,33 @@
+<article id="reshape"> <title/Reshaping a Cluster/
+
+<para>If you rearrange the nodes so that they serve different purposes, this will likely lead to the subscribers changing a bit.
+
+<para>This will require doing several things:
+<itemizedlist>
+
+<listitem><para> If you want a node that is a subscriber to become the "master" provider for a particular replication set, you will have to issue the slonik MOVE SET operation to change that "master" provider node.
+
+<listitem><para> You may subsequently, or instead, wish to modify the subscriptions of other nodes.  You might want to modify a node to get its data from a different provider, or to change it to turn forwarding on or off.  This can be accomplished by issuing the slonik SUBSCRIBE SET operation with the new subscription information for the node; Slony-I will change the configuration.
+
+<listitem><para> If the directions of data flows have changed, it is doubtless appropriate to issue a set of DROP LISTEN operations to drop out obsolete paths between nodes and SET LISTEN to add the new ones.  At present, this is not changed automatically; at some point, MOVE SET and SUBSCRIBE SET might change the paths as a side-effect.  See SlonyListenPaths for more information about this.  In version 1.1 and later, it is likely that the generation of sl_listen entries will be entirely automated, where they will be regenerated when changes are made to sl_path or sl_subscribe, thereby making it unnecessary to even think about SET LISTEN.
+
+</itemizedlist>
+<para> The "altperl" toolset includes a "init_cluster.pl" script that is quite up to the task of creating the new SET LISTEN commands; it isn't smart enough to know what listener paths should be dropped.
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
\ No newline at end of file
--- /dev/null
+++ doc/adminguide/startslons.sgml
@@ -0,0 +1,39 @@
+<article id="slonstart"> <title/Slon daemons/
+
+<para>The programs that actually perform Slony-I replication are the "slon" daemons.
+
+<para>You need to run one "slon" instance for each node in a Slony-I cluster, whether you consider that node a "master" or a "slave."  Since a MOVE SET or FAILOVER can switch the roles of nodes, slon needs to be able to function for both providers and subscribers.  It is not essential that these daemons run on any particular host, but there are some principles worth considering:
+<itemizedlist>
+<listitem><Para> Each slon needs to be able to communicate quickly with the database whose "node controller" it is.  Therefore, if a Slony-I cluster runs across some form of Wide Area Network, each slon process should run on or nearby the databases each is controlling.  If you break this rule, no particular disaster should ensue, but the added latency introduced to monitoring events on the slon's "own node" will cause it to replicate in a _somewhat_ less timely manner.
+
+<listitem><Para> The fastest results would be achieved by having each slon run on the database server that it is servicing.  If it runs somewhere within a fast local network, performance will not be noticeably degraded.
+
+<listitem><Para> It is an attractive idea to run many of the slon processes for a cluster on one machine, as this makes it easy to monitor them both in terms of log files and process tables from one location.  This eliminates the need to login to several hosts in order to look at log files or to restart slon instances.
+</itemizedlist>
+
+<para>There are two "watchdog" scripts currently available:
+<itemizedlist>
+
+<listitem><Para> tools/altperl/slon_watchdog.pl  - an "early" version that basically wraps a loop around the invocation of slon, restarting any time it  falls over
+<listitem><Para> tools/altperl/slon_watchdog2.pl - a somewhat more intelligent version that periodically polls the database, checking to see if a SYNC has taken place recently.  We have had VPN connections that occasionally fall over without signalling the application, so that the slon stops working, but doesn't actually die; this polling accounts for that...
+</itemizedlist>
+
+<para>The <filename/slon_watchdog2.pl/ script is probably <emphasis/usually/ the preferable thing to run.  It was at one point not preferable to run it whilst subscribing a very large replication set where it is expected to take many hours to do the initial <command/COPY SET/.  The problem that came up in that case was that it figured that since it hasn't done a <command/SYNC/ in 2 hours, something was  broken requiring  restarting slon, thereby restarting the <command/COPY SET/ event.  More recently, the script has been changed to detect <command/COPY SET/ in progress.
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/addthings.sgml
@@ -0,0 +1,36 @@
+<article id="addingthings"> <title/ Adding Things to Replication/
+
+<para>You may discover that you have missed replicating things that you wish you were replicating.
+
+<para>This can be fairly easily remedied.
+
+<para>You cannot directly use SET ADD TABLE or SET ADD SEQUENCE in
+order to add tables and sequences to a replication set that is
+presently replicating; you must instead create a new replication set.
+Once it is identically subscribed (e.g. - the set of subscribers is
+<emphasis/identical/ to that for the set it is to merge with), the
+sets may be merged together using MERGE SET.
+
+<para>Up to and including 1.0.2, there is a potential problem where if MERGE_SET is issued when other subscription-related events are pending, it is possible for things to get pretty confused on the nodes where other things were pending.  This problem was resolved in 1.0.5.
+
+<para>It is suggested that you be very deliberate when adding such things.  For instance, submitting multiple subscription requests for a particular set in one Slonik script often turns out quite badly.  If it is truly necessary to automate this, you'll probably want to submit WAIT FOR EVENT requests in between subscription requests in order that the Slonik script wait for one subscription to complete processing before requesting the next one.
+
+<para>But in general, it is likely to be easier to cope with complex node reconfigurations by making sure that one change has been successfully processed before going on to the next.  It's way easier to fix one thing that has broken than the interaction of five things that have broken.
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/intro.sgml
@@ -0,0 +1,103 @@
+<article id="slonyintroduction"> <title/Introduction to Slony-I/
+
+<sect1> <title>Why yet another replication system? </title>
+
+<para>Slony-I was born from an idea to create a replication system that was not tied
+to a specific version of PostgreSQL, which is allowed to be started and stopped on
+an existing database with out the need for a dump/reload cycle.
+
+<sect1> <title/What Slony-I is/
+
+<para>Slony-I is a <quote/master to multiple slaves/ replication
+system supporting cascading and slave promotion.  The big picture for
+the development of Slony-I is as a master-slave system that includes
+all features and capabilities needed to replicate large databases to a
+reasonably limited number of slave systems.  "Reasonable," in this
+context, is probably no more than a few dozen servers.  If the number
+of servers grows beyond that, the cost of communications becomes
+prohibitively high.  
+
+<!-- See also <link linkend="SlonyListenerCosts"> SlonyListenerCosts </link> -->
+
+<para> Slony-I is a system intended for data centers and backup sites,
+where the normal mode of operation is that all nodes are available all
+the time, and where all nodes can be secured.  If you have nodes that
+are likely to regularly drop onto and off of the network, or have
+nodes that cannot be kept secure, Slony-I may not be the ideal
+replication solution for you.
+
+<para> There are plans for a <quote/file-based log shipping/ extension where updates would be serialized into files.  Given that, log files could be distributed by any means desired without any need of feedback between the provider node and those nodes subscribing via "log shipping."
+
+
+<sect1><title/ Slony-I is not/
+
+<para>Slony-I is not a network management system.  
+
+<para> Slony-I does not have any functionality within it to detect a
+node failure, or automatically promote a node to a master or other
+data origin.
+
+<para>Slony-I is not multi-master; it's not a connection broker, and
+it doesn't make you coffee and toast in the morning.
+
+<para>(That being said, the plan is for a subsequent system, Slony-II,
+to provide "multimaster" capabilities, and be "bootstrapped" using
+Slony-I.  But that is a separate project, and expectations for Slony-I
+should not be based on hopes for future projects.)
+
+<sect1><title> Why doesn't Slony-I do automatic fail-over/promotion? 
+</title>
+
+<para>This is the job of network monitoring software, not Slony.
+Every site's configuration and fail-over path is different.  For
+example, keep-alive monitoring with redundant NIC's and intelligent HA
+switches that guarantee race-condition-free takeover of a network
+address and disconnecting the "failed" node vary in every network
+setup, vendor choice, hardware/software combination.  This is clearly
+the realm of network management software and not Slony-I.
+
+<para>Let Slony-I do what it does best: provide database replication.
+
+<sect1><title/ Current Limitations/
+
+<para>Slony-I does not automatically propagate schema changes, nor
+does it have any ability to replicate large objects.  There is a
+single common reason for these limitations, namely that Slony-I
+operates using triggers, and neither schema changes nor large object
+operations can raise triggers suitable to tell Slony-I when those
+kinds of changes take place.
+
+<para>There is a capability for Slony-I to propagate DDL changes if
+you submit them as scripts via the slonik <command/EXECUTE SCRIPT/
+operation.  That is not "automatic;" you have to construct an SQL DDL
+script and submit it.
+
+<para>If you have those sorts of requirements, it may be worth
+exploring the use of PostgreSQL 8.0 PITR (Point In Time Recovery),
+where WAL logs are replicated to remote nodes.  Unfortunately, that
+has two attendant limitations:
+
+<itemizedlist>
+	<listitem><para> PITR replicates <emphasis/all/ changes in <emphasis/all/ databases; you cannot exclude data that isn't relevant;
+	<listitem><para> A PITR replica remains dormant until you apply logs and start up the database.  You cannot use the database and apply updates simultaneously.  It is like having a <quote/standby server/ which cannot be used without it ceasing to be <quote/standby./
+
+</itemizedlist>
+
+<para>There are a number of distinct models for database replication; it is impossible for one replication system to be all things to all people.
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:slony.sgml
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
\ No newline at end of file
--- /dev/null
+++ doc/adminguide/ddlchanges.sgml
@@ -0,0 +1,39 @@
+<article id="ddlchanges"> <title/Database Schema Changes (DDL)
+
+<para>When changes are made to the database schema, e.g. adding fields to a table, it is necessary for this to be handled rather carefully, otherwise different nodes may get rather deranged because they disagree on how particular tables are built.
+
+<para>If you pass the changes through Slony-I via the EXECUTE SCRIPT (slonik) / <function/ddlscript(set,script,node)/ (stored function), this allows you to be certain that the changes take effect at the same point in the transaction streams on all of the nodes.  That may not be too important if you can take something of an outage to do schema changes, but if you want to do upgrades that take place while transactions are still firing their way through your systems, it's necessary.
+
+<para>It's worth making a couple of comments on "special things" about EXECUTE SCRIPT:
+<itemizedlist>
+<Listitem><Para> The script must not contain transaction BEGIN or END statements, as the script is already executed inside a transaction.  In PostgreSQL version 8, the introduction of nested transactions may change this requirement somewhat, but you must still remain aware that the actions in the script are wrapped inside a transaction.
+
+<Listitem><Para> If there is <emphasis/anything/ broken about the script, or about how it executes on a particular node, this will cause the slon daemon for that node to panic and crash.	If you restart the node, it will, more likely than not, try to <emphasis/repeat/ the DDL script, which will, almost certainly, fail the second time just as it did the first time.  I have found this scenario to lead to a need to go to the "master" node to delete the event to stop it from continuing to fail.
+
+<Listitem><Para> For slon to, at that point, "panic" is probably the <emphasis/correct/ answer, as it allows the DBA to head over to the database node that is broken, and manually fix things before cleaning out the defective event and restarting slon.  You can be certain that the updates made <emphasis/after/ the DDL change on the provider node are queued up, waiting to head to the subscriber.  You don't run the risk of there being updates made that depended on the DDL changes in order to be correct.
+
+</itemizedlist>
+
+<para>Unfortunately, this nonetheless implies that the use of the DDL facility is somewhat fragile and dangerous.  Making DDL changes should not be done in a sloppy or cavalier manner.  If your applications do not have fairly stable SQL schemas, then using Slony-I for replication is likely to be fraught with trouble and frustration.
+
+<para>There is an article on how to manage Slony schema changes here:
+<ulink url="http://www.varlena.com/varlena/GeneralBits/88.php">
+Varlena General Bits</ulink>
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/stylesheet.css
@@ -0,0 +1,67 @@
+/* $PostgreSQL: pgsql/doc/src/sgml/stylesheet.css,v 1.7 2004/06/29 20:44:34 petere Exp $ */
+
+/* color scheme similar to www.postgresql.org */
+
+BODY {
+	color: #000000;
+	background: #FFFFFF;
+}
+
+A:link		{ color: #000066; }
+A:visited	{ color: #000099; }
+A:active	{ color: #FF0000; }
+
+/* center titles */
+
+BODY.BOOK H1.TITLE, BODY.SET H1.TITLE {
+	text-align: center;
+	font-size: 250%;
+	font-family: sans-serif;
+	color: #020167;
+}
+
+BODY.BOOK H3.CORPAUTHOR, BODY.SET H3.CORPAUTHOR {
+	text-align: center;
+	font-style: italic;
+	font-weight: normal;
+}
+
+BODY.BOOK .COPYRIGHT, BODY.SET .COPYRIGHT {
+	text-align: center;
+}
+
+/* decoration for formal examples */
+
+DIV.EXAMPLE {
+	padding-left: 15px;
+	border-style: solid;
+	border-width: 0px;
+	border-left-width: 2px;
+	border-color: black;
+	margin: 0.5ex;
+}
+
+/* less dense spacing of TOC */
+
+.SET .TOC DL DT, .BOOK .TOC DL DT {
+	padding-top: 1.5ex;
+	padding-bottom: 1.5ex;
+}
+
+.SET .TOC DL DL DT, .BOOK .TOC DL DL DT {
+	padding-top: 0ex;
+	padding-bottom: 0ex;
+}
+
+.SCREEN, .SYNOPSIS, .PROGRAMLISTING {
+	margin-left: 4ex;
+}
+
+/* miscellaneous */
+
+.NAVHEADER TH	{ font-style: italic; }
+.COMMENT	{ color: red; }
+
+VAR		{ font-family: monospace; font-style: italic; }
+/* Konqueror's standard style for ACRONYM is italic. */
+ACRONYM		{ font-style: inherit; }
--- /dev/null
+++ doc/adminguide/stylesheet.dsl
@@ -0,0 +1,663 @@
+<!-- $ID$ --> 
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+
+<!-- must turn on one of these with -i on the jade command line -->
+<!ENTITY % output-html          "IGNORE">
+<!ENTITY % output-print         "IGNORE">
+<!ENTITY % output-text          "IGNORE">
+
+<![ %output-html; [
+<!ENTITY dbstyle PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
+]]>
+
+<![ %output-print; [
+<!ENTITY dbstyle PUBLIC "-//Norman Walsh//DOCUMENT DocBook Print Stylesheet//EN" CDATA DSSSL>
+]]>
+
+<![ %output-text; [
+<!ENTITY dbstyle PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
+]]>
+
+]>
+
+<style-sheet>
+ <style-specification use="docbook">
+  <style-specification-body> 
+
+<!-- general customization ......................................... -->
+
+<!-- (applicable to all output formats) -->
+
+(define draft-mode              #f)
+
+(define slony-list "slony1-general at gborg.postgresql.org")
+
+;; Don't show manpage volume numbers
+(define %refentry-xref-manvolnum% #f)
+
+;; Don't use graphics for callouts.  (We could probably do that, but
+;; it needs extra work.)
+(define %callout-graphics%      #f)
+
+;; Show comments during the development stage.
+(define %show-comments%         draft-mode)
+
+;; Don't append period if run-in title ends with any of these
+;; characters.  We had to add the colon here.  This is fixed in
+;; stylesheets version 1.71, so it can be removed sometime.
+(define %content-title-end-punct% 
+  '(#\. #\! #\? #\:))
+
+;; No automatic punctuation after honorific name parts
+(define %honorific-punctuation% "")
+
+;; Change display of some elements
+(element command ($mono-seq$))
+(element envar ($mono-seq$))
+(element lineannotation ($italic-seq$))
+(element literal ($mono-seq$))
+(element option ($mono-seq$))
+(element parameter ($mono-seq$))
+(element structfield ($mono-seq$))
+(element structname ($mono-seq$))
+(element symbol ($mono-seq$))
+(element token ($mono-seq$))
+(element type ($mono-seq$))
+(element varname ($mono-seq$))
+(element (programlisting emphasis) ($bold-seq$)) ;; to highlight sections of code
+
+;; Special support for Tcl synopses
+(element optional
+  (if (equal? (attribute-string (normalize "role")) "tcl")
+      (make sequence
+        (literal "?")
+        ($charseq$)
+        (literal "?"))
+      (make sequence
+        (literal %arg-choice-opt-open-str%)
+        ($charseq$)
+        (literal %arg-choice-opt-close-str%))))
+
+;; Avoid excessive cross-reference labels
+(define (auto-xref-indirect? target ancestor)
+  (cond
+;   ;; Always add indirect references to another book
+;   ((member (gi ancestor) (book-element-list))
+;    #t)
+   ;; Add indirect references to the section or component a block
+   ;; is in iff chapters aren't autolabelled.  (Otherwise "Figure 1-3"
+   ;; is sufficient)
+   ((and (member (gi target) (block-element-list))
+         (not %chapter-autolabel%))
+    #t)
+   ;; Add indirect references to the component a section is in if
+   ;; the sections are not autolabelled
+   ((and (member (gi target) (section-element-list))
+         (member (gi ancestor) (component-element-list))
+         (not %section-autolabel%))
+    #t)
+   (else #f)))
+
+
+;; Bibliography things
+
+;; Use the titles of bibliography entries in cross-references
+(define biblio-xref-title       #t)
+
+;; Process bibliography entry components in the order shown below, not
+;; in the order they appear in the document.  (I suppose this should
+;; be made to fit some publishing standard.)
+(define %biblioentry-in-entry-order% #f)
+
+(define (biblioentry-inline-elements)
+  (list
+   (normalize "author")
+   (normalize "authorgroup")
+   (normalize "title")
+   (normalize "subtitle")   
+   (normalize "volumenum")
+   (normalize "edition")
+   (normalize "othercredit")
+   (normalize "contrib")
+   (normalize "editor")
+   (normalize "publishername")
+   (normalize "confgroup")
+   (normalize "publisher")
+   (normalize "isbn")
+   (normalize "issn")
+   (normalize "pubsnumber")
+   (normalize "date")
+   (normalize "pubdate")
+   (normalize "pagenums")
+   (normalize "bibliomisc")))
+
+(mode biblioentry-inline-mode
+
+  (element confgroup
+    (make sequence
+      (literal "Proc. ")
+      (next-match)))
+
+  (element isbn
+    (make sequence
+      (literal "ISBN ")
+      (process-children)))
+
+  (element issn
+    (make sequence
+      (literal "ISSN ")
+      (process-children))))
+
+
+;; The rules in the default stylesheet for productname format it as a
+;; paragraph.  This may be suitable for productname directly within
+;; *info, but it's nonsense when productname is used inline, as we do.
+(mode set-titlepage-recto-mode
+  (element (para productname) ($charseq$)))
+(mode set-titlepage-verso-mode
+  (element (para productname) ($charseq$)))
+(mode book-titlepage-recto-mode
+  (element (para productname) ($charseq$)))
+(mode book-titlepage-verso-mode
+  (element (para productname) ($charseq$)))
+;; Add more here if needed...
+
+
+<!-- HTML output customization ..................................... -->
+
+<![ %output-html; [
+
+(define %section-autolabel%     #t)
+(define %label-preface-sections% #f)
+(define %generate-legalnotice-link% #t)
+(define %html-ext%              ".html")
+(define %root-filename%         "index")
+(define %link-mailto-url%       (string-append "mailto:" slony-list))
+(define %use-id-as-filename%    #t)
+(define %stylesheet%            "stylesheet.css")
+(define %graphic-default-extension% "gif")
+(define %gentext-nav-use-ff%    #t)
+(define %body-attr%             '())
+
+;; Returns the depth of auto TOC that should be made at the nd-level
+(define (toc-depth nd)
+  (cond ((string=? (gi nd) (normalize "book")) 2)
+	((string=? (gi nd) (normalize "set")) 2)
+	((string=? (gi nd) (normalize "part")) 2)
+	((string=? (gi nd) (normalize "chapter")) 2)
+	(else 1)))
+
+;; Put a horizontal line in the set TOC (just like the book TOC looks)
+(define (set-titlepage-separator side)
+  (if (equal? side 'recto)
+      (make empty-element gi: "HR")
+      (empty-sosofo)))
+
+;; Add character encoding and time of creation into HTML header
+(define %html-header-tags% 
+  (list (list "META" '("HTTP-EQUIV" "Content-Type") '("CONTENT" "text/html; charset=ISO-8859-1"))
+	(list "META" '("NAME" "creation") (list "CONTENT" (time->string (time) #t)))))
+
+;; Create an index
+(define html-index #t)
+
+
+;; Block elements are allowed in PARA in DocBook, but not in P in
+;; HTML.  With %fix-para-wrappers% turned on, the stylesheets attempt
+;; to avoid putting block elements in HTML P tags by outputting
+;; additional end/begin P pairs around them.
+(define %fix-para-wrappers% #t)
+
+;; ...but we need to do some extra work to make the above apply to PRE
+;; as well.  (mostly pasted from dbverb.dsl)
+(define ($verbatim-display$ indent line-numbers?)
+  (let ((content (make element gi: "PRE"
+                       attributes: (list
+                                    (list "CLASS" (gi)))
+                       (if (or indent line-numbers?)
+                           ($verbatim-line-by-line$ indent line-numbers?)
+                           (process-children)))))
+    (if %shade-verbatim%
+        (make element gi: "TABLE"
+              attributes: ($shade-verbatim-attr$)
+              (make element gi: "TR"
+                    (make element gi: "TD"
+                          content)))
+	(make sequence
+	  (para-check)
+	  content
+	  (para-check 'restart)))))
+
+;; ...and for notes.
+(element note
+  (make sequence
+    (para-check)
+    ($admonition$)
+    (para-check 'restart)))
+
+;;; XXX The above is very ugly.  It might be better to run 'tidy' on
+;;; the resulting *.html files.
+
+
+;; Format multiple terms in varlistentry vertically, instead
+;; of comma-separated.
+(element (varlistentry term)
+  (make sequence
+    (process-children-trim)
+    (if (not (last-sibling?))
+        (make empty-element gi: "BR")
+        (empty-sosofo))))
+
+]]> <!-- %output-html -->
+
+
+<!-- Print output customization .................................... -->
+
+<![ %output-print; [
+
+(define %section-autolabel%     #t)
+(define %default-quadding%      'justify)
+
+;; Don't know how well hyphenation works with other backends.  Might
+;; turn this on if desired.
+(define %hyphenation%
+  (if tex-backend #t #f))
+
+;; Put footnotes at the bottom of the page (rather than end of
+;; section), and put the URLs of links into footnotes.
+;;
+;; bop-footnotes only works with TeX, otherwise it's ignored.  But
+;; when both of these are #t and TeX is used, you need at least
+;; stylesheets 1.73 because otherwise you don't get any footnotes at
+;; all for the links.
+(define bop-footnotes           #t)
+(define %footnote-ulinks%       #t)
+
+(define %refentry-new-page%     #t)
+(define %refentry-keep%         #f)
+
+;; Indentation of verbatim environments.  (This should really be done
+;; with start-indent in DSSSL.)
+(define %indent-programlisting-lines% "    ")
+(define %indent-screen-lines% "    ")
+(define %indent-synopsis-lines% "    ")
+
+
+;; Default graphic format: Jadetex wants eps, pdfjadetex wants pdf.
+;; (Note that pdfjadetex will not accept eps, that's why we need to
+;; create a different .tex file for each.)  What works with RTF?
+
+(define texpdf-output #f) ;; override from command line
+
+(define %graphic-default-extension%
+  (cond (tex-backend (if texpdf-output "pdf" "eps"))
+	(rtf-backend "gif")
+	(else "XXX")))
+
+;; Need to add pdf here so that the above works.  Default setup
+;; doesn't know about PDF.
+(define preferred-mediaobject-extensions
+  (list "eps" "ps" "jpg" "jpeg" "pdf" "png"))
+
+
+;; Don't show links when citing a bibliography entry.  This fouls up
+;; the footnumber counting.  To get the link, one can still look into
+;; the bibliography itself.
+(mode xref-title-mode
+  (element ulink
+    (process-children)))
+
+
+;; Format legalnotice justified and with space between paragraphs.
+(mode book-titlepage-verso-mode
+  (element (legalnotice para)
+    (make paragraph
+      use: book-titlepage-verso-style	;; alter this if ever it needs to appear elsewhere
+      quadding: %default-quadding%
+      line-spacing: (* 0.8 (inherited-line-spacing))
+      font-size: (* 0.8 (inherited-font-size))
+      space-before: (* 0.8 %para-sep%)
+      space-after: (* 0.8 %para-sep%)
+      first-line-start-indent: (if (is-first-para)
+				   (* 0.8 %para-indent-firstpara%)
+				   (* 0.8 %para-indent%))
+      (process-children))))
+
+
+;; Fix spacing problems in variablelists
+
+(element (varlistentry term)
+  (make paragraph
+    space-before: (if (first-sibling?)
+		      %para-sep%
+		      0pt)
+    keep-with-next?: #t
+    (process-children)))
+
+(define %varlistentry-indent% 2em)
+
+(element (varlistentry listitem)
+  (make sequence
+    start-indent: (+ (inherited-start-indent) %varlistentry-indent%)
+    (process-children)))
+
+
+;; Whitespace fixes for itemizedlists and orderedlists
+
+(define (process-listitem-content)
+  (if (absolute-first-sibling?)
+      (make sequence
+        (process-children-trim))
+      (next-match)))
+
+
+;; Default stylesheets format simplelists as tables.  This spells
+;; trouble for Jade.  So we just format them as plain lines.
+
+(define %simplelist-indent% 1em)
+
+(define (my-simplelist-vert members)
+  (make display-group
+    space-before: %para-sep%
+    space-after: %para-sep%
+    start-indent: (+ %simplelist-indent% (inherited-start-indent))
+    (process-children)))
+
+(element simplelist
+  (let ((type (attribute-string (normalize "type")))
+        (cols (if (attribute-string (normalize "columns"))
+                  (if (> (string->number (attribute-string (normalize "columns"))) 0)
+                      (string->number (attribute-string (normalize "columns")))
+                      1)
+                  1))
+        (members (select-elements (children (current-node)) (normalize "member"))))
+    (cond
+       ((equal? type (normalize "inline"))
+	(if (equal? (gi (parent (current-node)))
+		    (normalize "para"))
+	    (process-children)
+	    (make paragraph
+	      space-before: %para-sep%
+	      space-after: %para-sep%
+	      start-indent: (inherited-start-indent))))
+       ((equal? type (normalize "vert"))
+        (my-simplelist-vert members))
+       ((equal? type (normalize "horiz"))
+        (simplelist-table 'row    cols members)))))
+ 
+(element member
+  (let ((type (inherited-attribute-string (normalize "type"))))
+    (cond
+     ((equal? type (normalize "inline"))
+      (make sequence
+	(process-children)
+	(if (not (last-sibling?))
+	    (literal ", ")
+	    (literal ""))))
+      ((equal? type (normalize "vert"))
+       (make paragraph
+	 space-before: 0pt
+	 space-after: 0pt))
+      ((equal? type (normalize "horiz"))
+       (make paragraph
+	 quadding: 'start
+	 (process-children))))))
+
+
+;; Jadetex doesn't handle links to the content of tables, so
+;; indexterms that point to table entries will go nowhere.  We fix
+;; this by pointing the index entry to the table itself instead, which
+;; should be equally useful in practice.
+
+(define (find-parent-table nd)
+  (let ((table (ancestor-member nd ($table-element-list$))))
+    (if (node-list-empty? table)
+	nd
+	table)))	 
+
+;; (The function below overrides the one in print/dbindex.dsl.)
+
+(define (indexentry-link nd)
+  (let* ((id        (attribute-string (normalize "role") nd))
+         (prelim-target (find-indexterm id))
+         (target    (find-parent-table prelim-target))
+         (preferred (not (node-list-empty?
+                          (select-elements (children (current-node))
+                                           (normalize "emphasis")))))
+         (sosofo    (if (node-list-empty? target)
+                        (literal "?")
+                        (make link
+                          destination: (node-list-address target)
+                          (with-mode toc-page-number-mode
+                            (process-node-list target))))))
+    (if preferred
+        (make sequence
+          font-weight: 'bold
+          sosofo)
+        sosofo)))
+
+
+;; By default, the part and reference title pages get wrong page
+;; numbers: The first title page gets roman numerals carried over from
+;; preface/toc -- we want arabic numerals.  We also need to make sure
+;; that page-number-restart is set of #f explicitly, because otherwise
+;; it will carry over from the previous component, which is not good.
+;;
+;; (This looks worse than it is.  It's copied from print/dbttlpg.dsl
+;; and common/dbcommon.dsl and modified in minor detail.)
+
+(define (first-part?)
+  (let* ((book (ancestor (normalize "book")))
+	 (nd   (ancestor-member (current-node)
+				(append
+				 (component-element-list)
+				 (division-element-list))))
+	 (bookch (children book)))
+    (let loop ((nl bookch))
+      (if (node-list-empty? nl)
+	  #f
+	  (if (equal? (gi (node-list-first nl)) (normalize "part"))
+	      (if (node-list=? (node-list-first nl) nd)
+		  #t
+		  #f)
+	      (loop (node-list-rest nl)))))))
+
+(define (first-reference?)
+  (let* ((book (ancestor (normalize "book")))
+	 (nd   (ancestor-member (current-node)
+				(append
+				 (component-element-list)
+				 (division-element-list))))
+	 (bookch (children book)))
+    (let loop ((nl bookch))
+      (if (node-list-empty? nl)
+	  #f
+	  (if (equal? (gi (node-list-first nl)) (normalize "reference"))
+	      (if (node-list=? (node-list-first nl) nd)
+		  #t
+		  #f)
+	      (loop (node-list-rest nl)))))))
+
+
+(define (part-titlepage elements #!optional (side 'recto))
+  (let ((nodelist (titlepage-nodelist 
+		   (if (equal? side 'recto)
+		       (reference-titlepage-recto-elements)
+		       (reference-titlepage-verso-elements))
+		   elements))
+        ;; partintro is a special case...
+	(partintro (node-list-first
+		    (node-list-filter-by-gi elements (list (normalize "partintro"))))))
+    (if (part-titlepage-content? elements side)
+	(make simple-page-sequence
+	  page-n-columns: %titlepage-n-columns%
+	  ;; Make sure that page number format is correct.
+	  page-number-format: ($page-number-format$)
+	  ;; Make sure that the page number is set to 1 if this is the
+	  ;; first part in the book
+	  page-number-restart?: (first-part?)
+	  input-whitespace-treatment: 'collapse
+	  use: default-text-style
+	  
+	  ;; This hack is required for the RTF backend. If an external-graphic
+	  ;; is the first thing on the page, RTF doesn't seem to do the right
+	  ;; thing (the graphic winds up on the baseline of the first line
+	  ;; of the page, left justified).  This "one point rule" fixes
+	  ;; that problem.
+	  (make paragraph
+	    line-spacing: 1pt
+	    (literal ""))
+      
+	  (let loop ((nl nodelist) (lastnode (empty-node-list)))
+	    (if (node-list-empty? nl)
+		(empty-sosofo)
+		(make sequence
+		  (if (or (node-list-empty? lastnode)
+			  (not (equal? (gi (node-list-first nl))
+				       (gi lastnode))))
+		      (part-titlepage-before (node-list-first nl) side)
+		      (empty-sosofo))
+		  (cond
+		   ((equal? (gi (node-list-first nl)) (normalize "subtitle"))
+		    (part-titlepage-subtitle (node-list-first nl) side))
+		   ((equal? (gi (node-list-first nl)) (normalize "title"))
+		    (part-titlepage-title (node-list-first nl) side))
+		   (else
+		    (part-titlepage-default (node-list-first nl) side)))
+		  (loop (node-list-rest nl) (node-list-first nl)))))
+
+	  (if (and %generate-part-toc%
+		   %generate-part-toc-on-titlepage%
+		   (equal? side 'recto))
+	      (make display-group
+		(build-toc (current-node)
+			   (toc-depth (current-node))))
+	      (empty-sosofo))
+
+	  ;; PartIntro is a special case
+	  (if (and (equal? side 'recto)
+		   (not (node-list-empty? partintro))
+		   %generate-partintro-on-titlepage%)
+	      ($process-partintro$ partintro #f)
+	      (empty-sosofo)))
+
+	(empty-sosofo))))
+
+
+(define (reference-titlepage elements #!optional (side 'recto))
+  (let ((nodelist (titlepage-nodelist 
+		   (if (equal? side 'recto)
+		       (reference-titlepage-recto-elements)
+		       (reference-titlepage-verso-elements))
+		   elements))
+        ;; partintro is a special case...
+	(partintro (node-list-first
+		    (node-list-filter-by-gi elements (list (normalize "partintro"))))))
+    (if (reference-titlepage-content? elements side)
+	(make simple-page-sequence
+	  page-n-columns: %titlepage-n-columns%
+	  ;; Make sure that page number format is correct.
+	  page-number-format: ($page-number-format$)
+	  ;; Make sure that the page number is set to 1 if this is the
+	  ;; first part in the book
+	  page-number-restart?: (first-reference?)
+	  input-whitespace-treatment: 'collapse
+	  use: default-text-style
+	  
+	  ;; This hack is required for the RTF backend. If an external-graphic
+	  ;; is the first thing on the page, RTF doesn't seem to do the right
+	  ;; thing (the graphic winds up on the baseline of the first line
+	  ;; of the page, left justified).  This "one point rule" fixes
+	  ;; that problem.
+	  (make paragraph
+	    line-spacing: 1pt
+	    (literal ""))
+      
+	  (let loop ((nl nodelist) (lastnode (empty-node-list)))
+	    (if (node-list-empty? nl)
+		(empty-sosofo)
+		(make sequence
+		  (if (or (node-list-empty? lastnode)
+			  (not (equal? (gi (node-list-first nl))
+				       (gi lastnode))))
+		      (reference-titlepage-before (node-list-first nl) side)
+		      (empty-sosofo))
+		  (cond
+		   ((equal? (gi (node-list-first nl)) (normalize "author"))
+		    (reference-titlepage-author (node-list-first nl) side))
+		   ((equal? (gi (node-list-first nl)) (normalize "authorgroup"))
+		    (reference-titlepage-authorgroup (node-list-first nl) side))
+		   ((equal? (gi (node-list-first nl)) (normalize "corpauthor"))
+		    (reference-titlepage-corpauthor (node-list-first nl) side))
+		   ((equal? (gi (node-list-first nl)) (normalize "editor"))
+		    (reference-titlepage-editor (node-list-first nl) side))
+		   ((equal? (gi (node-list-first nl)) (normalize "subtitle"))
+		    (reference-titlepage-subtitle (node-list-first nl) side))
+		   ((equal? (gi (node-list-first nl)) (normalize "title"))
+		    (reference-titlepage-title (node-list-first nl) side))
+		   (else
+		    (reference-titlepage-default (node-list-first nl) side)))
+		  (loop (node-list-rest nl) (node-list-first nl)))))
+
+	  (if (and %generate-reference-toc%
+		   %generate-reference-toc-on-titlepage%
+		   (equal? side 'recto))
+	      (make display-group
+		(build-toc (current-node)
+			   (toc-depth (current-node))))
+	      (empty-sosofo))
+
+	  ;; PartIntro is a special case
+	  (if (and (equal? side 'recto)
+		   (not (node-list-empty? partintro))
+		   %generate-partintro-on-titlepage%)
+	      ($process-partintro$ partintro #f)
+	      (empty-sosofo)))
+
+	(empty-sosofo))))
+
+]]> <!-- %output-print -->
+
+
+<!-- Plain text output customization ............................... -->
+
+<!--
+This is used for making the INSTALL file and others.  We customize the
+HTML stylesheets to be suitable for dumping plain text (via Netscape,
+Lynx, or similar).
+-->
+
+<![ %output-text; [
+
+(define %section-autolabel% #f)
+(define %chapter-autolabel% #f)
+(define $generate-chapter-toc$ (lambda () #f))
+
+;; For text output, produce "ASCII markup" for emphasis and such.
+
+(define ($asterix-seq$ #!optional (sosofo (process-children)))
+  (make sequence
+    (literal "*")
+    sosofo
+    (literal "*")))
+ 
+(define ($dquote-seq$ #!optional (sosofo (process-children)))
+  (make sequence
+    (literal (gentext-start-quote))
+    sosofo
+    (literal (gentext-end-quote))))
+ 
+(element (para command) ($dquote-seq$))
+(element (para emphasis) ($asterix-seq$))
+(element (para filename) ($dquote-seq$))
+(element (para option) ($dquote-seq$))
+(element (para replaceable) ($dquote-seq$))
+(element (para userinput) ($dquote-seq$))
+
+]]> <!-- %output-text -->
+
+  </style-specification-body>
+ </style-specification>
+
+ <external-specification id="docbook" document="dbstyle">
+</style-sheet>
--- /dev/null
+++ doc/adminguide/failover.sgml
@@ -0,0 +1,136 @@
+<article id="failover"> <title/Doing switchover and failover with Slony-I/
+
+<sect1><title/Foreword/
+
+<para>	 Slony-I is an asynchronous replication system.  Because of that, it
+	 is almost certain that at the moment the current origin of a set
+	 fails, the last transactions committed have not propagated to the
+	 subscribers yet.  They always fail under heavy load, and you know
+	 it.  Thus the goal is to prevent the main server from failing.
+	 The best way to do that is frequent maintenance.
+<para>
+	 Opening the case of a running server is not exactly what we
+	 all consider professional system maintenance.  And interestingly,
+	 those users who use replication for backup and failover
+	 purposes are usually the ones that have a very low tolerance for
+	 words like "downtime".  To meet these requirements, Slony-I has
+	 not only failover capabilities, but controlled master role transfer
+	 features too.
+
+<para>	 It is assumed in this document that the reader is familiar with
+	 the slonik utility and knows at least how to set up a simple
+	 2 node replication system with Slony-I.
+
+<sect1><title/ Switchover
+
+<para>	 We assume a current "origin" as node1 (AKA master) with one 
+	 "subscriber" as node2 (AKA slave).  A web application on a third
+	 server is accessing the database on node1.  Both databases are
+	 up and running and replication is more or less in sync.
+
+<itemizedlist>
+
+		<listitem><para>  At the time of this writing switchover to another server requires the application to reconnect to the database.  So in order to avoid	 any complications, we simply shut down the web server.  Users who use pg_pool for the applications database connections can shutdown	  the pool only.
+
+
+		<listitem><para> A small slonik script executes the following commands:
+<para><command>
+	lock set (id = 1, origin = 1);
+	wait for event (origin = 1, confirmed = 2);
+	move set (id = 1, old origin = 1, new origin = 2);
+	wait for event (origin = 1, confirmed = 2);
+</command>
+
+<para>	 After these commands, the origin (master role) of data set 1
+	 is now on node2.  It is not simply transferred.  It is done
+	 in a fashion so that node1 is now a fully synchronized subscriber
+	 actively replicating the set.  So the two nodes completely switched
+	 roles.
+
+<listitem><Para>	 After reconfiguring the web application (or pgpool) to connect to	 the database on node2 instead, the web server is restarted and	 resumes normal operation.
+
+<para>	 Done in one shell script, that does the shutdown, slonik, move
+	 config files and startup all together, this entire procedure
+	 takes less than 10 seconds.
+
+</itemizedlist>
+<para>	 It is now possible to simply shutdown node1 and do whatever is
+	 required.  When node1 is restarted later, it will start replicating
+	 again and eventually catch up after a while.  At this point the
+	 whole procedure is executed with exchanged node IDs and the
+	 original configuration is restored.
+
+<sect1><title/ Failover/
+
+<para>	 Because of the possibility of missing not-yet-replicated
+	 transactions that are committed, failover is the worst thing
+	 that can happen in a master-slave replication scenario.  If there
+	 is any possibility to bring back the failed server even if only
+	 for a few minutes, we strongly recommended that you follow the
+	 switchover procedure above.
+
+<para>	 Slony does not provide any automatic detection for failed systems.
+	 Abandoning committed transactions is a business decision that
+	 cannot be made by a database.  If someone wants to put the
+	 commands below into a script executed automatically from the
+	 network monitoring system, well ... its your data.
+<itemizedlist>
+<listitem><para>
+	The slonik command
+<para><command>
+	failover (id = 1, backup node = 2);
+</command>
+
+<para>	 causes node2 to assume the ownership (origin) of all sets that
+	 have node1 as their current origin.  In the case there would be
+	 more nodes, All direct subscribers of node1 are instructed that
+	 this is happening.  Slonik would also query all direct subscribers
+	 to figure out which node has the highest replication status
+	 (latest committed transaction) for each set, and the configuration
+	 would be changed in a way that node2 first applies those last
+	 minute changes before actually allowing write access to the
+	 tables.
+
+<para>	 In addition, all nodes that subscribed directly from node1 will
+	 now use node2 as data provider for the set.  This means that
+	 after the failover command succeeded, no node in the entire
+	 replication setup will receive anything from node1 any more.
+<listitem><para>
+
+	 Reconfigure and restart the application (or pgpool) to cause it
+	 to reconnect to node2.
+
+<listitem><para>
+	 After the failover is complete and node2 accepts write operations
+	 against the tables, remove all remnants of node1's configuration
+	 information with the slonik command
+
+<para><command>
+	drop node (id = 1, event node = 2);
+</command>
+</itemizedlist>
+
+<sect1><title/After failover, getting back node1/
+<para>
+	 After the above failover, the data stored on node1 must be
+	 considered out of sync with the rest of the nodes.  Therefore, the
+	 only way to get node1 back and transfer the master role to it is
+	 to rebuild it from scratch as a slave, let it catch up and then
+	 follow the switchover procedure.
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/monitoring.sgml
@@ -0,0 +1,37 @@
+<article id="monitoring"> <title/Monitoring/
+
+<para>Here are some of things that you may find in your Slony logs, and explanations of what they mean. 
+
+<sect1><title/CONFIG notices/
+
+<para>These entries are pretty straightforward. They are informative messages about your configuration. 
+
+<para>Here are some typical entries that you will probably run into in your logs:
+
+<para><command>
+CONFIG main: local node id = 1
+CONFIG main: loading current cluster configuration
+CONFIG storeNode: no_id=3 no_comment='Node 3'
+CONFIG storePath: pa_server=5 pa_client=1 pa_conninfo="host=127.0.0.1 dbname=foo user=postgres port=6132" pa_connretry=10
+CONFIG storeListen: li_origin=3 li_receiver=1 li_provider=3
+CONFIG storeSet: set_id=1 set_origin=1 set_comment='Set 1'
+CONFIG main: configuration complete - starting threads
+</command>
+
+<sect1><title/DEBUG Notices/
+
+<para>Debug notices are always prefaced by the name of the thread that the notice originates from. You will see messages from the following threads:
+
+<para><command>
+localListenThread: This is the local thread that listens for events on the local node.
+remoteWorkerThread_X: The thread processing remote events.
+remoteListenThread_X: Listens for events on a remote node database.
+cleanupThread: Takes care of things like vacuuming, cleaning out the confirm and event tables, and deleting logs.
+syncThread: Generates sync events.
+</command>
+
+<para> WriteMe: I can't decide the format for the rest of this. I
+think maybe there should be a "how it works" page, explaining more
+about how the threads work, what to expect in the logs after you run a
+slonik command...
+
--- /dev/null
+++ doc/adminguide/installation.sgml
@@ -0,0 +1,84 @@
+<article id="installation"> <title/ Slony-I Installation
+
+<para>You should have obtained the Slony-I source from the previous step. Unpack it.
+
+<para><command>
+gunzip slony.tar.gz;
+tar xf slony.tar
+</command>
+
+<para> This will create a directory Slony-I under the current
+directory with the Slony-I sources.  Head into that that directory for
+the rest of the installation procedure.
+
+<sect1><title/ Short Version/
+
+<para>
+<command>./configure --with-pgsourcetree=/whereever/the/source/is </command>
+<para> <command> gmake all; gmake install </command>
+
+<sect1><title/ Configuration/
+
+<para>The first step of the installation procedure is to configure the source tree
+for your system.  This is done by running the configure script.  Configure
+needs to know where your PostgreSQL source tree is, this is done with the
+--with-pgsourcetree= option.
+
+<sect1><title/ Example/
+
+<para> <command>
+./configure --with-pgsourcetree=/usr/local/src/postgresql-7.4.3
+</command>
+
+<para>This script will run a number of tests to guess values for
+various dependent variables and try to detect some quirks of your
+system.  Slony-I is known to need a modified version of libpq on
+specific platforms such as Solaris2.X on SPARC this patch can be found
+at <ulink url=
+"http://developer.postgresql.org/~wieck/slony1/download/threadsafe-libpq-742.diff.gz">
+http://developer.postgresql.org/~wieck/slony1/download/threadsafe-libpq-742.diff.gz</ulinK>
+
+
+<sect1><title/ Build/
+
+<para>To start the build process, type
+
+<command>
+gmake all
+</command>
+
+<para> Be sure to use GNU make; on BSD systems, it is called gmake; on Linux, GNU make is typically the native "make", so the name of the command you type in may vary somewhat. The build may take anywhere from a few seconds to 2 minutes depending on how fast your hardware is at compiling things.  The last line displayed should be
+
+<para> <command>
+All of Slony-I is successfully made.  Ready to install.
+</command>
+
+<sect1><title/ Installing Slony-I/
+
+<para> To install Slony-I, enter
+
+<command>
+gmake install
+</command>
+
+<para>This will install files into postgresql install directory as
+specified by the --prefix option used in the PostgreSQL configuration.
+Make sure you have appropriate permissions to write into that area.
+Normally you need to do this either as root or as the postgres user.
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:slony.sgml
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/slonik.sgml
@@ -0,0 +1,55 @@
+<article id="slonik"> <title>Slonik</title>
+
+<sect1><title/Introduction/
+
+<para>Slonik is a command line utility designed specifically to setup
+and modify configurations of the Slony-I replication system.</para>
+
+<sect1><title/General outline/
+
+<para>The slonik command line utility is supposed to be used embedded
+into shell scripts and reads commands from files or stdin.</para>
+
+<para>It reads a set of Slonik statements, which are written in a
+scripting language with syntax similar to that of SQL, and performs
+the set of configuration changes on the slony nodes specified in the
+script.</para>
+
+<para>Nearly all of the real configuration work is actually done by
+calling stored procedures after loading the Slony-I support base into
+a database.  Slonik was created because these stored procedures have
+special requirements as to on which particular node in the replication
+system they are called.  The absence of named parameters for stored
+procedures makes it rather hard to do this from the psql prompt, and
+psql lacks the ability to maintain multiple connections with open
+transactions to multiple databases.</para>
+
+<para>The format of the Slonik "language" is very similar to that of
+SQL, and the parser is based on a similar set of formatting rules for
+such things as numbers and strings.  Note that slonik is declarative,
+using literal values throughout, and does <emphasis>not</emphasis> have the
+notion of variables.  It is anticipated that Slonik scripts will
+typically be <emphasis>generated</emphasis> by scripts, such as Bash or Perl,
+and these sorts of scripting languages already have perfectly good
+ways of managing variables.</para>
+
+<para>A detailed list of Slonik commands can be found here: <ulink
+url="http://gborg.postgresql.org/project/slony1/genpage.php?slonik_commands">
+slonik commands </ulink></para>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:slony.sgml
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/dropthings.sgml
@@ -0,0 +1,95 @@
+<article id="dropthings"> <title/ Dropping things from Slony Replication/
+
+<para>There are several things you might want to do involving dropping things from Slony-I replication.
+
+<sect1><title/ Dropping A Whole Node/
+
+<para>If you wish to drop an entire node from replication, the Slonik command DROP NODE should do the trick.  
+
+<para>This will lead to Slony-I dropping the triggers (generally that deny the ability to update data), restoring the "native" triggers, dropping the schema used by Slony-I, and the slon process for that node terminating itself.
+
+<para>As a result, the database should be available for whatever use your application makes of the database.
+
+<para>This is a pretty major operation, with considerable potential to cause substantial destruction; make sure you drop the right node!
+
+<para>The operation will fail if there are any nodes subscribing to the node that you attempt to drop, so there is a bit of failsafe.
+
+<para>SlonyFAQ17 documents some extra maintenance that may need to be done on sl_confirm if you are running versions prior to 1.0.5.
+
+<sect1><title/ Dropping An Entire Set/
+
+<para>If you wish to stop replicating a particular replication set, the Slonik command DROP SET is what you need to use.
+
+<para>Much as with DROP NODE, this leads to Slony-I dropping the Slony-I triggers on the tables and restoring "native" triggers.  One difference is that this takes place on *all* nodes in the cluster, rather than on just one node.  Another difference is that this does not clear out the Slony-I cluster's namespace, as there might be other sets being serviced.
+
+<para>This operation is quite a bit more dangerous than DROP NODE, as there _isn't_ the same sort of "failsafe."  If you tell DROP SET to drop the _wrong_ set, there isn't anything to prevent "unfortunate results."
+
+<sect1><title/ Unsubscribing One Node From One Set/
+
+<para>The UNSUBSCRIBE SET operation is a little less invasive than either DROP SET or DROP NODE; it involves dropping Slony-I triggers and restoring "native" triggers on one node, for one replication set.
+
+<para>Much like with DROP NODE, this operation will fail if there is a node subscribing to the set on this node. 
+
+<sect1><title/ Warning!!!/
+
+<para>For all of the above operations, "turning replication back on" will require that the node copy in a <emphasis/full/ fresh set of the data on a provider.  The fact that the data was recently being replicated isn't good enough; Slony-I will expect to refresh the data from scratch.
+
+<sect1><title/ Dropping A Table From A Set/
+
+<para>In Slony 1.0.5 and above, there is a Slonik command SET DROP TABLE that allows dropping a single table from replication without forcing the user to drop the entire replication set.
+
+<para>If you are running an earlier version, there is a "hack" to do this:
+
+<para>You can fiddle this by hand by finding the table ID for the table you want to get rid of, which you can find in sl_table, and then run the following three queries, on each host:
+
+<para><command>
+  select _slonyschema.alterTableRestore(40);
+  select _slonyschema.tableDropKey(40);
+  delete from _slonyschema.sl_table where tab_id = 40;
+</command>
+
+<para>The schema will obviously depend on how you defined the Slony-I cluster.  The table ID, in this case, 40, will need to change to the ID of the table you want to have go away.
+
+<para>You'll have to run these three queries on all of the nodes,
+preferably firstly on the "master" node, so that the dropping of this
+propagates properly.  Implementing this via a Slonik statement with a
+new Slony event would do that.  Submitting the three queries using
+EXECUTE SCRIPT could do that.  Also possible would be to connect to
+each database and submit the queries by hand.
+
+<sect1><title/ Dropping A Sequence From A Set/
+
+<para>Just as with SET DROP TABLE, version 1.0.5 introduces the operation SET DROP SEQUENCE.
+
+<para>If you are running an earlier version, here are instructions as to how to drop sequences:
+
+<para>The data that needs to be deleted to stop Slony from continuing to replicate the two sequences identified with Sequence IDs 93 and 59 are thus:
+
+<para><command>
+delete from _oxrsorg.sl_seqlog where seql_seqid in (93, 59);
+delete from _oxrsorg.sl_sequence where seq_id in (93,59);
+</command>
+
+<para> Those two queries could be submitted to all of the nodes via
+<function/ddlscript()/ / <command/EXECUTE SCRIPT/, thus eliminating
+the sequence everywhere "at once."  Or they may be applied by hand to
+each of the nodes.
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
+
--- /dev/null
+++ doc/adminguide/listenpaths.sgml
@@ -0,0 +1,129 @@
+<article id="listenpaths"> <title/ Slony Listen Paths
+
+<para>If you have more than two or three nodes, and any degree of usage of cascaded subscribers (_e.g._ - subscribers that are subscribing through a subscriber node), you will have to be fairly careful about the configuration of "listen paths" via the Slonik STORE LISTEN and DROP LISTEN statements that control the contents of the table sl_listen.
+
+<para>The "listener" entries in this table control where each node expects to listen in order to get events propagated from other nodes.  You might think that nodes only need to listen to the "parent" from whom they are getting updates, but in reality, they need to be able to receive messages from _all_ nodes in order to be able to conclude that SYNCs have been received everywhere, and that, therefore, entries in sl_log_1 and sl_log_2 have been applied everywhere, and can therefore be purged.
+
+<sect1><title/ How Listening Can Break
+
+<para>On one occasion, I had a need to drop a subscriber node (#2) and recreate it.  That node was the data provider for another subscriber (#3) that was, in effect, a "cascaded slave."  Dropping the subscriber node initially didn't work, as slonik informed me that there was a dependant node.  I repointed the dependant node to the "master" node for the subscription set, which, for a while, replicated without difficulties.
+
+<para>I then dropped the subscription on "node 2," and started resubscribing it.  That raised the Slony-I SET_SUBSCRIPTION event, which started copying tables.  At that point in time, events stopped propagating to "node 3," and while it was in perfectly OK shape, no events were making it to it.
+
+<para>The problem was that node #3 was expecting to receive events from node #2, which was busy processing the SET_SUBSCRIPTION event, and was not passing anything else on.
+
+<para>We dropped the listener rules that caused node #3 to listen to node 2, replacing them with rules where it expected its events to come from node  #1 (the "master" provider node for the replication set).  At that moment, "as if by magic," node #3 started replicating again, as it discovered a place to get SYNC events.
+
+<sect1><title/How The Listen Configuration Should Look/
+
+<para>The simple cases tend to be simple to cope with.  We'll look at a fairly complex set of nodes.
+
+<para>Consider a set of nodes, 1 thru 6, where 1 is the "master," where 2-4 subscribe directly to the master, and where 5 subscribes to 2, and 6 subscribes to 5.
+
+<para>Here is a "listener network" that indicates where each node should listen for messages coming from each other node:
+
+<para><command>
+		 1|	2|	3|	4|	5|	6|
+--------------------------------------------
+	1	0	 2	 3	 4	 2	 2 
+	2	1	 0	 1	 1	 5	 5 
+	3	1	 1	 0	 1	 1	 1 
+	4	1	 1	 1	 0	 1	 1 
+	5	2	 2	 2	 2	 0	 6 
+	6	5	 5	 5	 5	 5	 0 
+</command>
+
+<para>Row 2 indicates all of the listen rules for node 2; it gets events for nodes 1, 3, and 4 throw node 1, and gets events for nodes 5 and 6 from node 5.
+
+<para>The row of 5's at the bottom, for node 6, indicate that node 6 listens to node 5 to get events from nodes 1-5.
+
+<para>The set of slonik SET LISTEN statements to express this "listener network" are as follows:
+
+<para><command>
+		store listen (origin = 1, receiver = 2, provider = 1);
+		store listen (origin = 1, receiver = 3, provider = 1);
+		store listen (origin = 1, receiver = 4, provider = 1);
+		store listen (origin = 1, receiver = 5, provider = 2);
+		store listen (origin = 1, receiver = 6, provider = 5);
+		store listen (origin = 2, receiver = 1, provider = 2);
+		store listen (origin = 2, receiver = 3, provider = 1);
+		store listen (origin = 2, receiver = 4, provider = 1);
+		store listen (origin = 2, receiver = 5, provider = 2);
+		store listen (origin = 2, receiver = 6, provider = 5);
+		store listen (origin = 3, receiver = 1, provider = 3);
+		store listen (origin = 3, receiver = 2, provider = 1);
+		store listen (origin = 3, receiver = 4, provider = 1);
+		store listen (origin = 3, receiver = 5, provider = 2);
+		store listen (origin = 3, receiver = 6, provider = 5);
+		store listen (origin = 4, receiver = 1, provider = 4);
+		store listen (origin = 4, receiver = 2, provider = 1);
+		store listen (origin = 4, receiver = 3, provider = 1);
+		store listen (origin = 4, receiver = 5, provider = 2);
+		store listen (origin = 4, receiver = 6, provider = 5);
+		store listen (origin = 5, receiver = 1, provider = 2);
+		store listen (origin = 5, receiver = 2, provider = 5);
+		store listen (origin = 5, receiver = 3, provider = 1);
+		store listen (origin = 5, receiver = 4, provider = 1);
+		store listen (origin = 5, receiver = 6, provider = 5);
+		store listen (origin = 6, receiver = 1, provider = 2);
+		store listen (origin = 6, receiver = 2, provider = 5);
+		store listen (origin = 6, receiver = 3, provider = 1);
+		store listen (origin = 6, receiver = 4, provider = 1);
+		store listen (origin = 6, receiver = 5, provider = 6);
+</command>
+
+<para>How we read these listen statements is thus...
+
+<para>When on the "receiver" node, look to the "provider" node to provide events coming from the "origin" node.
+
+<para>The tool "init_cluster.pl" in the "altperl" scripts produces optimized listener networks in both the tabular form shown above as well as in the form of Slonik statements.
+
+<para>There are three "thorns" in this set of roses:
+<itemizedlist>
+<listitem><para> If you change the shape of the node set, so that the nodes subscribe differently to things, you need to drop sl_listen entries and create new ones to indicate the new preferred paths between nodes.  There is no automated way at this point to do this "reshaping."
+
+<listitem><para> If you _don't_ change the sl_listen entries, events will likely continue to propagate so long as all of the nodes continue to run well.  The problem will only be noticed when a node is taken down, "orphaning" any nodes that are listening through it.
+
+<listitem><para> You might have multiple replication sets that have _different_ shapes for their respective trees of subscribers.  There won't be a single "best" listener configuration in that case.
+
+	<listitem><para> In order for there to be an sl_listen path, there _must_ be a series of sl_path entries connecting the origin to the receiver.  This means that if the contents of sl_path do not express a "connected" network of nodes, then some nodes will not be reachable.  This would typically happen, in practice, when you have two sets of nodes, one in one subnet, and another in another subnet, where there are only a couple of "firewall" nodes that can talk between the subnets.  Cut out those nodes and the subnets stop communicating.
+</itemizedlist>
+
+<sect1><title/Open Question/
+
+<para>I am not certain what happens if you have multiple listen path entries for one path, that is, if you set up entries allowing a node to listen to multiple receivers to get events from a particular origin.  Further commentary on that would be appreciated!
+
+<sect1><title/ Generating listener entries via heuristics/
+
+<para>It ought to be possible to generate sl_listen entries dynamically, based on the following heuristics.  Hopefully this will take place in version 1.1, eliminating the need to configure this by hand.
+
+<para>Configuration will (tentatively) be controlled based on two data sources:
+<itemizedlist>
+<listitem><para> sl_subscribe entries are the first, most vital control as to what listens to what; we know there must be a "listen" entry for a subscriber node to listen to its provider for events from the provider, and there should be direct "listening" taking place between subscriber and provider.
+
+<listitem><para> sl_path entries are the second indicator; if sl_subscribe has not already indicated "how to listen," then a node may listen directly to the event's origin if there is a suitable sl_path entry
+
+<listitem><para> If there is no guidance thus far based on the above data sources, then nodes can listen indirectly if there is an sl_path entry that points to a suitable sl_listen entry...
+</itemizedlist>
+
+<para> A stored procedure would run on each node, rewriting sl_listen
+each time sl_subscribe or sl_path are modified.
+
+
+</article>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+++ doc/adminguide/slony.sgml
@@ -0,0 +1,77 @@
+<!--
+$PostgreSQL: pgsql/doc/src/sgml/postgres.sgml,v 1.68 2004/12/03 05:50:18 momjian Exp $
+-->
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
+
+<!entity % filelist SYSTEM "filelist.sgml">
+%filelist;
+
+<!entity reference  SYSTEM "reference.sgml">
+
+]>
+
+<book id="slony">
+ <title>Slony 1.1 Documentation</title>
+
+ <bookinfo>
+  <corpauthor>The PostgreSQL Global Development Group</corpauthor>
+  &legal;
+ </bookinfo>
+<part id="overview"> <title/Overview/
+
+ &intro;
+ &prerequisites;
+ &installation;
+ &slonik;
+ &concepts;
+ &cluster;
+ &defineset;
+</part>
+
+<part id="tools"> <title/Tools/
+ &adminscripts;
+ &startslons;
+ &slonconfig;
+ &subscribenodes;
+ &monitoring;
+ &maintenance;
+ &reshape;
+ &failover;
+ &listenpaths;
+ &addthings;
+ &dropthings;
+ &ddlchanges;
+ &firstdb;
+ &help;
+
+</part>
+
+<!--  <part id="appendixes"> -->
+<!--   <title>Appendixes</title> -->
+
+<!--   &errcodes; -->
+
+<!--  </part> -->
+
+<!--  &biblio; -->
+<!--  &bookindex; -->
+
+</book>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode:sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"./reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+End:
+-->


More information about the Slony1-commit mailing list