<!--  -->
<sect1 id="concepts">
<title>&slony1; Concepts</title>

<indexterm><primary>concepts and terminology</primary></indexterm>

<para>In order to set up a set of &slony1; replicas, it is necessary
to understand the following major abstractions that it uses:</para>

<itemizedlist>
	<listitem><para>Cluster</para></listitem>
	<listitem><para>Node</para></listitem>
	<listitem><para>Replication Set</para></listitem>
	<listitem><para>Origin, Providers and Subscribers</para></listitem>
        <listitem><para>slon daemons</para></listitem>
        <listitem><para>slonik configuration processor</para></listitem>
</itemizedlist>

<para> It is also worth knowing the meanings of certain Russian words:</para>
<itemizedlist>
<listitem><para>slon is Russian for <quote>elephant</quote></para></listitem>
<listitem><para>slony is the plural of slon, and therefore refers to a group of elephants</para></listitem>
<listitem><para>slonik is Russian for <quote>little elephant</quote></para></listitem>
</itemizedlist>

<para> The use of these terms in &slony1; is a <quote>tip of the
hat</quote> to Vadim Mikheev, who was responsible for the
<application>rserv</application> prototype which inspired some of the
algorithms used in &slony1;.</para>

<sect2>
<title>Cluster</title>
<indexterm>
 <primary>cluster</primary>
</indexterm>

<para>In &slony1; terms, a <quote>cluster</quote> is a named set of
&postgres; database instances; replication takes place between those
databases.</para>

<para>The cluster name is specified in each and every Slonik script via the directive:</para>
<programlisting>
cluster name = something;
</programlisting>

<para>If the Cluster name is <envar>something</envar>, then &slony1;
will create, in each database instance in the cluster, the
namespace/schema <envar>_something.</envar></para>
</sect2>
<sect2><title>Node</title>
<indexterm>
<primary>node</primary>
</indexterm>

<para>A &slony1; Node is a named &postgres; database that will be
participating in replication.</para>

<para>It is defined, near the beginning of each Slonik script, using the directive:</para>
<programlisting>
 NODE 1 ADMIN CONNINFO = 'dbname=testdb host=server1 user=slony';
</programlisting>

<para>The <xref linkend="admconninfo"> information indicates database
connection information that will ultimately be passed to the
<function>PQconnectdb()</function> libpq function.</para>

<para>Thus, a &slony1; cluster consists of:</para>
<itemizedlist>
	<listitem><para> A cluster name</para></listitem>
	<listitem><para> A set of &slony1; nodes, each of which has a namespace based on that cluster name</para></listitem>
</itemizedlist>
</sect2>
<sect2><title> Replication Set</title>
<indexterm>
<primary>replication set</primary>
</indexterm>

<para>A replication set is defined as a set of tables and sequences
that are to be replicated between nodes in a &slony1; cluster.</para>

<para>You may have several sets, and the <quote>flow</quote> of
replication does not need to be identical between those sets.</para>
</sect2>

<sect2><title> Origin, Providers and Subscribers</title>
<indexterm>
<primary>origin node</primary>
</indexterm>
<indexterm>
<primary>provider node</primary>
</indexterm>

<para>Each replication set has some origin node, which is the
<emphasis>only</emphasis> place where user applications are permitted
to modify data in the tables that are being replicated.  This might
also be termed the <quote>master provider</quote>; it is the main
place from which data is provided.</para>

<indexterm>
<primary>subscriber node</primary>
</indexterm>

<para>Other nodes in the cluster subscribe to the replication set,
indicating that they want to receive the data.</para>

<para>The origin node will never be considered a
<quote>subscriber.</quote> (Ignoring the case where the cluster is
reshaped, and the origin is expressly shifted to another node.)  But
&slony1; supports the notion of cascaded subscriptions, that is, a
node that is subscribed to some set may also behave as a
<quote>provider</quote> to other nodes in the cluster for that
replication set.</para>
</sect2>

<sect2><title>slon Daemon</title>

<indexterm><primary>slon daemon</primary></indexterm>

<para>For each node in the cluster, there will be a <xref
linkend="slon"> process to manage replication activity for that node.
</para>

<para> <xref linkend="slon"> is a program implemented in C that
processes replication events.  There are two main sorts of events:</para>

<itemizedlist>

<listitem><para> Configuration events</para>

<para> These normally occur when a <xref linkend="slonik"> script is
run, and submit updates to the configuration of the cluster. </para>
</listitem>

<listitem><para> <command>SYNC</command> events </para>

<para> Updates to the tables that are replicated are grouped together
into <command>SYNC</command>s; these groups of transactions are
applied together to the subscriber nodes.  </para>
</listitem>
</itemizedlist>
</sect2>

<sect2><title>slonik Configuration Processor</title>

<indexterm><primary>slonik configuration processor</primary></indexterm>

<para> The <xref linkend="slonik"> command processor processes scripts
in a <quote>little language</quote> that are used to submit events to
update the configuration of a &slony1; cluster.  This includes such
things as adding and removing nodes, modifying communications paths,
adding or removing subscriptions.
</para>
</sect2>


<sect2 id="plainpaths"><title> &slony1; Path Communications</title>

<indexterm><primary>communication paths</primary></indexterm>

<para> &slony1; uses &postgres; DSNs in three contexts to establish
access to databases:

<itemizedlist>

<listitem><para> <xref linkend="admconninfo"> - controlling how a
<xref linkend="slonik"> script accesses the various nodes.</para>

<para> These connections are the ones that go from your
<quote>administrative workstation</quote> to all of the nodes in a &slony1;
cluster.</para>

<para> It is <emphasis>vital</emphasis> that you have connections from the
central location where you run <xref linkend="slonik"> 
to each and every node in the network.  These connections are only
used briefly, to submit the few <acronym>SQL</acronym> requests required to
control the administration of the cluster.</para>

<para> Since these communications paths are only used briefly, it may
be quite reasonable to <quote>hack together</quote> temporary
connections using SSH tunnelling.</para></listitem>

<listitem><para> The &lslon; DSN parameter. </para>

<para> The DSN parameter passed to each &lslon; indicates what network
path should be used to get from the &lslon; process to the database
that it manages.</para> </listitem>

<listitem><para> <xref linkend="stmtstorepath"> - controlling how
&lslon; daemons communicate with remote nodes.  These paths are stored
in <xref linkend="table.sl-path">.</para>

<para> You forcibly <emphasis>need</emphasis> to have a path between
each subscriber node and its provider; other paths are optional, and
will not be used unless a listen path in <xref
linkend="table.sl-listen">. is needed that uses that particular
path.</para></listitem>

</itemizedlist></para>

<para> The distinctions and possible complexities of paths are not
normally an issue for people with simple networks where all the hosts
can see one another via a comparatively <quote>global</quote> set of
network addresses.  In contrast, it matters rather a lot for those
with complex firewall configurations, nodes at multiple locations, and
the issue where nodes may not be able to all talk to one another via a
uniform set of network addresses.</para>

<para> Consider the attached diagram, which describes a set of six
nodes

<inlinemediaobject> <imageobject> <imagedata fileref="complexenv.png">
</imageobject> <textobject> <phrase> Symmetric Multisites </phrase>
</textobject> </inlinemediaobject></para>

<itemizedlist>

<listitem><para> DB1 and DB2 are databases residing in a secure
<quote>database layer,</quote> firewalled against outside access
except from specifically controlled locations.</para>

<para> Let's suppose that DB1 is the origin node for the replication
system.</para></listitem>

<listitem><para> DB3 resides in a <quote>DMZ</quote> at the same site;
it is intended to be used as a &slony1; <quote>provider</quote> for
remote locations.</para></listitem>
<listitem><para> DB4 is a counterpart to DB3 in a <quote>DMZ</quote>
at a secondary/failover site.  Its job, in the present configuration,
is to <quote>feed</quote> servers in the secure database layers at the
secondary site.</para></listitem>
<listitem><para> DB5 and DB6 are counterparts to DB1 and DB2, but
are, at present, configured as subscribers.</para>

<para> Supposing disaster were to strike at the <quote>primary</quote>
site, the secondary site would be well-equipped to take over servicing
the applications that use this data.</para>

<listitem><para> The symmetry of the configuration means that if you
had <emphasis>two</emphasis> transactional applications needing
protection from failure, it would be straightforward to have
additional replication sets so that each site is normally
<quote>primary</quote> for one application, and where destruction of
one site could be addressed by consolidating services at the remaining
site.</para></listitem>

</itemizedlist>

<sect2><title>SSH tunnelling</title>
<para>
If a direct connection to &postgres; can not be established because of a 
firewall then you can establish an ssh tunnel that &slony1; can operate
over. </para>

<para>
SSH tunnels can be configured by passing the <option>w</option> to SSH.
This enables  forwarding &postgres; traffic where a local port is forwarded 
across a connection, encrypted and compressed, using 
<application>SSH</application></para>

<para> See the  <application>ssh</application> documentation for details on how to configure and use SSH tunnels.</para>
</sect2>

</sect1>
<!-- 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-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->
