<!--  -->
<sect1 id="slonyupgrade">
<title> &slony1; Upgrade </title>
<indexterm><primary>Upgrading between minor slony versions</primary></indexterm>
<para> Minor &slony1; versions can be upgraded using the slonik <xref
linkend="stmtupdatefunctions"> command.  This includes upgrades from
2.2.x to a newer version 2.2.y version or from 2.0.x to 2.1.y. </para>
<para> When upgrading &slony1;, the installation on all nodes in a
cluster must be upgraded at once, using the &lslonik;
command <xref linkend="stmtupdatefunctions">.</para>

<para> While this requires temporarily stopping replication, it does
not forcibly require an outage for applications that submit
updates. </para>

<para>The proper upgrade procedure is thus:</para>
<itemizedlist>
<listitem><para> Stop the &lslon; processes on all nodes.
(<emphasis>e.g.</emphasis> - old version of &lslon;)</para></listitem>
<listitem><para> Install the new version of &lslon; software on all
nodes.</para></listitem>
<listitem><para> Execute a &lslonik; script containing the
command <command>update functions (id = [whatever]);</command> for
each node in the cluster.</para>
<note><para>Remember that your slonik upgrade script like all other 
slonik scripts must contain the proper preamble commands to function.
</para></note></listitem>
<listitem><para> Start all slons.  </para> </listitem>
</itemizedlist>

<para> The overall operation is relatively safe: If there is any
mismatch between component versions, the &lslon; will refuse to start
up, which provides protection against corruption. </para>

<para> You need to be sure that the C library containing SPI trigger
functions and the slony SQL files that get installed into the share 
directory are installed on your database server.  The slony version
number will be part of these files so they can be installed on your
database server before the upgrade and co-exist with the old version
of &slony1;
</para>

<sect2><title>Upgrade from 2.1 to 2.2</title> 

<para> In &slony1; 2.2, we change the layout of tables &sllog1; and
&sllog2;.  This does not prevent an in-place upgrade from version 2.1,
however it does require that there be no unreplicated data lingering
in &sllog1; and &sllog2;.  </para>

<para> If any data remains unconfirmed, then <xref
linkend="stmtupdatefunctions"> will fail with the message:
<screen>
cannot upgrade to new sl_log_N format due to existing unreplicated data
</screen>
</para>
<para> A suggested approach is as follows:
<itemizedlist>
<listitem><para> Use <xref linkend="stmtlockset"> to lock all sets, so that no new changes are being injected into the log tables </para></listitem>
<listitem><para> Set &lslon; parameter <xref linkend="slon-config-cleanup-interval"> to a very low value (a few seconds) so that the &lslon; cleanup thread will trim data out of &sllog1; and &sllog2; immediately</para></listitem>
<listitem><para> Restart &lslon; for each node and let it run through a cleanup cycle to empty out &sllog1; and &sllog2; on all nodes. </para>
</listitem>
<listitem><para> Verify that &sllog1; and &sllog2; are empty on all nodes in the cluster. </para></listitem>
<listitem><para> Use <xref
linkend="stmtupdatefunctions"> against each node to upgrade to version 2.2  </para></listitem>
<listitem><para> Use <xref linkend="stmtunlockset"> to unlock all sets </para></listitem>
</itemizedlist>
</para>
</sect2>


<sect2>
<title>Incompatibilities between 2.1 and 2.2</title>

<indexterm><primary>incompatibilities between versions</primary></indexterm>
<sect3><title>Slony Log Tables</title>
<para>
The format of the slony log tables sl_log_1 and sl_log_2 has changed.  The data to be 
replicated is now stored in an array of of column names and values.  It was previously stored
as the text that would make up the SQL command.
</para>
</sect3>

<sect3><title>FAILOVER changes</title>
<para>
The syntax of the <xref linkend="stmtfailover"> command has changed.  If multiple nodes
in the cluster have failed, including subscriber-only nodes, then all failed nodes must be passed
to the failover command.  The rules concerning which nodes can be a failover node have also
changed.</para>
</sect3>

<sect3><title>Reshaping subscriptions</title>
<para>
Prior to slony 2.2.0 you could use the <xref linkend="stmtsubscribeset"> command to change
a subscribers provider to a different provider for a set.  As of &slony1; 2.2.0 the 
<xref linkend="stmtsubscribeset"> command can only be used to establish an initial subscription.
The <xref linkend="stmtresubscribenode" > command has been introduced to change the provider
node.

</para>
</sect3>

<sect3>
<title>EXECUTE SCRIPT OPTIONS</title>
<para>
The <xref linkend="stmtddlscript"> command no longer accepts SET ID as a valid option.
</para>

</sect3>

<sect3>
<title>LOG SHIPPING</title>
<para>
The format of the .SQL files generated for log shipping has changed. Prior to &slony1; 2.2.0 
these files contained SQL INSERT/UPDATE/DELETE statements.  They now contain a COPY statement
that inserts these changes into a sl_log_archive table.  A trigger will then apply these changes
on the log shipping target.
</para>
</sect3>

<sect3>
<title>Installable files are now versioned</title>
<para>
The files that get installed on database servers in the $libdir and $sharedir now
have the &slony1; version number as part of the file name. For example
slony1_funcs.so is now slony1_funcs.2.2.0.so and slony1_funcs.sql is now
slony1_funcs.2.2.0.sql 
</para>


</sect2>


<sect2>
<title>Incompatibilities between 2.0 and 2.1</title>
<indexterm><primary>incompatibilities between versions</primary></indexterm>
<sect3><title>Automatic Wait For</title>
<para>
Slonik will now sometimes wait for previously submitted events
to be confirmed before submittng additional events.  This is described
in <xref linkend="events">
</para>
</sect3>

<sect3><title>SNMP Support</title>
<para>
In version 2.0 &slony1; could be built with SNMP support.  This allowed
&slony1; to send SNMP messages.  This has been removed in version 2.1
</para>


</sect2>


<sect2>
<title>Incompatibilities between 1.2 and 2.0</title>

<indexterm><primary>incompatibilities between versions</primary></indexterm>

<sect3> <title> TABLE ADD KEY issue in &slony1; 2.0 </title> 
<para> The TABLE ADD KEY slonik command has been removed in version 2.0.
This means that all tables must have a set of columns that form a 
unique key for the table.

If you are upgrading from a previous &slony1; version and are using a 
&slony1; created primary key then you will need to modify your table
to have its own primary key before installing &slony1; version 2.0

<sect3> <title> New Trigger Handling in &slony1; Version 2 </title>

<para> One of the major changes to &slony1; is that enabling/disabling
of triggers and rules now takes place as plain SQL, supported by
&postgres; 8.3+, rather than via <quote>hacking</quote> on the system
catalog. </para>

<para> As a result, &slony1; users should be aware of the &postgres;
syntax for <command>ALTER TABLE</command>, as that is how they can
accomplish what was formerly accomplished via <xref
linkend="stmtstoretrigger"> and <xref linkend="stmtdroptrigger">. </para>

</sect3>

<sect3><title>SUBSCRIBE SET goes to the origin</title>

<para> New in 2.0.5 (but not older versions of 2.0.x) is that 
<xref linkend="stmtsubscribeset"> commands are submitted by
slonik to the set origin not the provider.  This means that you
only need to issue <xref linkend="stmtwaitevent"> on the set origin
to wait for the subscription process to complete.
</para>
</sect3>
<sect3><title>WAIT FOR EVENT requires WAIT ON</title>
<para> With version 2.0 the WAIT FOR EVENT slonik command requires
that the WAIT ON parameter be specified.  Any slonik scripts that
were assuming a default value will need to be modified
</para>
</sect3>

<sect2 id="upgrade21"> <title> Upgrading to &slony1; version 2.1
from version 2.0</title>

<para>
&slony1; version 2.0 can be upgraded to version 2.1 using the 
 &lslonik; command <xref linkend="stmtupdatefunctions">.</para>

<para> While this requires temporarily stopping replication, it does
not forcibly require an outage for applications that submit
updates. </para>

<para>The proper upgrade procedure is thus:</para>
<itemizedlist>
<listitem><para> Stop the &lslon; processes on all nodes.
(<emphasis>e.g.</emphasis> - old version of &lslon;)</para></listitem>
<listitem><para> Install the new version of &slony1;; software on all
nodes (including new versions of the shared functions
and libraries) .</para></listitem>
<listitem><para> Execute a &lslonik; script containing the
command <command>update functions (id = [whatever]);</command> for
each node in the cluster. This will alter the structure of
some of the &slony1; configuration tables.</para>
<note><para>Remember that your slonik upgrade script like all other 
slonik scripts must contain the proper preamble commands to function.
</para></note></listitem>
<listitem><para> Start all slons.  </para> </listitem>
</itemizedlist>
</sect2>

<sect2 id="upgrade20"> <title> Upgrading to &slony1; version 2.1
from version 1.2 or earlier </title>

<indexterm><primary>upgrading to &slony1; version 2</primary></indexterm>

<para> The version 2 branch is <emphasis>substantially</emphasis>
different from earlier releases, dropping support for versions of
&postgres; prior to 8.3, as in version 8.3, support for a
<quote>session replication role</quote> was added, thereby eliminating
the need for system catalog hacks as well as the
not-entirely-well-supported <envar>xxid</envar> data type. </para>

<para> As a result of the replacement of the <envar>xxid</envar> type
with a (native-to-8.3) &postgres; transaction XID type, the &lslonik;
command <xref linkend="stmtupdatefunctions"> is quite inadequate to
the process of upgrading earlier versions of &slony1; to version
2.</para>

<para> In version 2.0.2, we have added a new option to <xref
linkend="stmtsubscribeset">, <command>OMIT COPY</command>, which
allows taking an alternative approach to upgrade which amounts to:</para>

<itemizedlist>
<listitem><para> Uninstall old version of &slony1; </para>
<para> When &slony1; uninstalls itself, catalog corruptions are fixed back up.</para> </listitem>
<listitem><para> Install &slony1; version 2 </para></listitem>
<listitem><para> Resubscribe, with <command>OMIT COPY</command></para></listitem>
</itemizedlist>

<warning><para> There is a large <quote>foot gun</quote> here: during
part of the process, &slony1; is not installed in any form, and if an
application updates one or another of the databases, the
resubscription, omitting copying data, will be left with data
<emphasis>out of sync.</emphasis> </para>

<para> The administrator <emphasis>must take care</emphasis>; &slony1;
has no way to help ensure the integrity of the data during this
process.</para>
</warning>

<para> The following process is suggested to help make the upgrade
process as safe as possible, given the above risks. </para>

<itemizedlist>

<listitem><para> Use <xref linkend="slonikconfdump"> to generate a
&lslonik; script to recreate the replication cluster.  </para>

<para> Be sure to verify the <xref linkend="admconninfo"> statements,
as the values are pulled are drawn from the PATH configuration, which
may not necessarily be suitable for running &lslonik;. </para>

<para> This step may be done before the application outage. </para>
</listitem>

<listitem><para> Determine what triggers have <xref
linkend="stmtstoretrigger"> configuration on subscriber nodes.
</para>

<para>Trigger handling has
fundamentally changed between &slony1; 1.2 and 2.0. </para>

<para> Generally speaking, what needs to happen is to query
<envar>sl_table</envar> on each node, and, for any triggers found in
<envar>sl_table</envar>, it is likely to be appropriate to set up a
script indicating either <command>ENABLE REPLICA TRIGGER</command> or
<command>ENABLE ALWAYS TRIGGER</command> for these triggers.</para>

<para> This step may be done before the application outage. </para>
</listitem>

<listitem><para> Begin an application outage during which updates should no longer be applied to the database. </para> </listitem>

<listitem><para> To ensure that applications cease to make changes, it would be appropriate to lock them out via modifications to <filename>pg_hba.conf</filename> </para> </listitem>

<listitem><para> Ensure replication is entirely caught up, via examination of the <envar>sl_status</envar> view, and any application data that may seem appropriate. </para> </listitem>

<listitem><para> Shut down &lslon; processes. </para> </listitem>

<listitem><para> Uninstall the old version of &slony1; from the database. </para> 

<para> This involves running a &lslonik; script that runs <xref
linkend="stmtuninstallnode"> against each node in the cluster. </para>

</listitem>

<listitem><para> Ensure new &slony1; binaries are in place. </para> 

<para> A convenient way to handle this is to have old and new in different directories alongside two &postgres; builds, stop the <application>postmaster</application>, repoint to the new directory, and restart the <application>postmaster</application>. </para>
</listitem>

<listitem><para> Run the script that reconfigures replication as generated earlier.  </para> 

<para> This script should probably be split into two portions to be run separately:</para> 
<itemizedlist>
<listitem><para> Firstly, set up nodes, paths, sets, and such </para> </listitem>
<listitem><para> At this point, start up &lslon; processes </para> </listitem>
<listitem><para> Then, run the portion which runs <xref linkend="stmtsubscribeset"> </para> </listitem>
</itemizedlist>

<para> Splitting the <xref linkend="slonikconfdump"> script as described above is left as an exercise for the reader.</para>
</listitem>

<listitem><para> If there were triggers that needed to be activated on subscriber nodes, this is the time to activate them. </para> </listitem>
<listitem><para> At this point, the cluster should be back up and running, ready to be reconfigured so that applications may access it again.  </para> </listitem>

</itemizedlist>

</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:
-->
