<!--  -->
<sect1 id="events">
<title>Events & Confirmations</title>
<indexterm><primary>events and confirmations</primary></indexterm>
<para>
&slony1; transfers configuration changes and application data through
events.   Events in &slony1; have an origin, a type and some parameters.   
When an event is created it is inserted
into the event queue (the <xref linkend="table.sl-event"> table) on the node the event
originates on.  The remoteListener threads for each remote &lslon; process then picks up
that event (by querying the table &slevent;) and pass the event to the
&lslon;'s remoteWorker thread for processing.
</para>

<para>
An event is uniquely identified via the combination of the node id of the node the
event originates on and the event sequence number for that node.
For example, (1,5000001) identifies event 5000001 originating from node 1.
In contrast, (3,5000001) identifies a different event that originated on a 
different node.
</para>

<sect2>
<title>SYNC Events</title>
<para>
SYNC events are used to transfer application data for one node to the next.
When data in a replicated table changes, a trigger fires that records information
about the change in the &sllog1; or &sllog2; tables.  The localListener thread
in the slon processes will then periodically generate a SYNC event.  When the
SYNC event is created, &slony1; will determine the highest log_seqid assigned so far
along with a list of log_seqid's that were assigned to transactions that
have not yet been committed.  This information is all stored as part of the SYNC 
event.
</para>


<para>
When the remoteWorker thread for a &lslon; processes a SYNC, it
queries the rows from &sllog1; and &sllog2; that are covered by the
SYNC (<emphasis>e.g.</emphasis> - log_seqid rows that had been
committed at the time the SYNC was generated).  The data modifications
indicated by this logged data are then applied to the subscriber.
</para>

</sect2>


<sect2>
<title>Event Confirmations</title>
<para>
When an event is processed by the &lslon; process for a remote node, a CONFIRM message
is generated by inserting a tuple into the &slconfirm; table.  This tuple indicates
that a particular event has been confirmed by a particular receiver node.
Confirmation messages are then transferred back to all other nodes in the cluster.
</para>
</sect2>

<sect2>
<title>Event cleanup</title>
<para>
The &lslon; cleanupThread periodically runs the <xref
linkend="function.cleanupevent-p-interval-interval"> database function
that deletes all but the most recently confirmed event for each
origin/receiver pair (this is safe to do because if an event has been
confirmed by a receiver, then we know that all older events from that
origin have also been confirmed by the receiver).  Then the function
deletes all SYNC events that are older than the oldest row left in
&slconfirm; (for each origin). The data for these deleted events will
also be removed from the &sllog1; and &sllog2; tables.
</para>

<para>
When &slony1; is first enabled it will log the data to replicate to
the &sllog1; table.  After a while it will stop logging to &sllog1;
and switch to logging in &sllog2;.  When all the data in &sllog1; is
known to have been replicated to all the other nodes, &slony1; will
TRUNCATE the &sllog1; table, clearing out this now-obsolete
replication data.  Then, it stops logging to &sllog2;, switching back
to logging to the freshly truncated &sllog1; table.  This process is
repeated periodically as &slony1; runs, keeping these tables from
growing uncontrollably.  By using TRUNCATE, we guarantee that the
tables are properly emptied out.
</para>

</sect2>

<sect2>
<title>Slonik and Event Confirmations</title>
<para>

&lslonik; can submit configuration commands to different event nodes,
as controlled by the parameters of each slonik command.  If two
commands are submitted to different nodes, it might be important to
ensure they are processed by other nodes in a consistent order.  The
&lslonik; <xref linkend="stmtwaitevent"> command may be used to
accomplish this, but as of &slony1; 2.1 this consistency is handled
automatically by &lslonik; under a number of circumstances.
</para>
<orderedlist>
<listitem><para>Before slonik submits an event to a node,
it waits until that node has confirmed the last configuration event
from the previous event node.</para></listitem>

<listitem><para>Before slonik submits a <xref
linkend="stmtsubscribeset"> command, it verifies that the provider
node has confirmed all configuration events from all other
nodes.</para></listitem>

<listitem><para>Before &lslonik; submits a <xref
linkend="stmtdropNode"> event, it verifies that all nodes in the
cluster (aside from the one being dropped, of course!) have already
caught up with all other nodes</para></listitem>

<listitem><para>Before slonik submits a <xref linkend="stmtcloneprepare">
it verifies that the node being cloned is caught up with all other
nodes in the cluster.</para></listitem>

<listitem><para>Before slonik submits a <xref linkend="stmtcreateset"> command
it verifies that any <xref linkend="stmtdropset"> commands have been confirmed by
all nodes.</para></listitem>

</orderedlist>
<para>

When &lslonik; starts up, it contacts all nodes for which it has <xref
linkend="admconninfo"> information, to find the last non-SYNC event
from each node.  Submitting commands from multiple &lslonik; instances
at the same time will confuse &lslonik; and is not recommended.
Whenever &lslonik; is waiting for an event confirmation, it displays a
message every 10 seconds indicating which events are still
outstanding.  Any commands that might require slonik to wait for event
confirmations may not be validly executed within a <link
linkend="tryblock">try block</link> for the very same reasons that
<xref linkend="stmtwaitevent"> command may not be used within a <link
linkend="tryblock">try block</link>, namely that it is not reasonable
to ask &slony1; to try to roll back events.
</para>

<para>
Automatic waiting for confirmations may be disabled in &lslonik; by
running &lslonik; with the <option>-w</option> option.</para>

</sect2>
</sect1>
