<!--  -->
<sect1 id="ddlchanges">
<title>Database Schema Changes (DDL)</title>

<indexterm>
 <primary>DDL changes</primary>
 <secondary>database schema changes</secondary>
</indexterm>

<para>When changes are made to the database schema,
<emphasis>e.g.</emphasis> - 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>


<para>&slony1; can not automatically detect and replicate database schema
changes however, &slony1; does provide facilities to assist in making 
database schema changes.  Schema changes can be done on a replicated
database either by using the &slony1;  <xref
linkend="stmtddlscript"> (slonik) command or by manually applying the
changes to each node.</para>

<sect2>
<title>DDL Changes with Execute Script</title>
<para>
The <xref linkend="stmtddlscript"> (slonik) command allows you to submit
a SQL script (that can, but is not required to) contain DDL commands. 
This script will be executed on the event node and then (optionally) replicated
to every other node in the cluster.  You should keep the following in mind
when using <xref linkend="stmtddlscript">
<para>

<itemizedlist>

<listitem><para>The script <emphasis>must not</emphasis> contain
transaction <command>BEGIN</command> or <command>END</command>
statements, as the script is already executed inside a transaction
though nested transactions are allowed as long are processed
within the scope of a single transaction whose <command>BEGIN</command> 
and <command>END</command> you do not control.</para></listitem>

<listitem><para>If there is <emphasis>anything</emphasis> broken about
the script, or about how it executes on a particular node (other than
the event node), this will
cause the <xref linkend="slon"> daemon for that node to panic and crash.  
You may see various expected messages (positive and negative)
in <xref linkend="ddllogs">.  If you restart the slon, it will,
most likely, try to
<emphasis>repeat</emphasis> the DDL script, which will, almost
certainly, fail the second time in the same way it did the first time.
</para>

<para> The implication of this is that it is
<emphasis>vital</emphasis> that modifications not be made in a
haphazard way on one node or another.  The schemas must always stay in
sync.  If slon; fails due to a failed DDL change then
you should manually (via psql) make the required changes so that the
DDL change succeeds the next time slon attempts it.
</para></listitem>

<listitem><para>&slony1; 2.0.x and 2.1.x suffer from an issue where
concurrent transactions involving the same tables as are referenced
in the script might not be replayed in exactly the same order on the
replica nodes.  It is advisiable to not be concurrently inserting,deleting
or updating rows to a table while a script changing that table (adding or
deleting columns) is also running.</para></listitem>

</itemizedlist>

</sect2>


<sect2>
<title>Applying DDL Changes Directly</title>
<para>DDL changes can be applied directly on a node through an 
application such as psql.  The DDL changes will not be replicated by &slony1;
and therefore must be manually applied to every relevant node.
The following points should be kept in mind when applying DDL changes
directly.

<itemizedlist>
<listitem><para>While DDL changes are not replicated any  
INSERT,UPDATE,DELETE statements that you execute will be replicated.
This means that you should put DDL changes inside of the same script
as DML commands because the script will then not behave properly when
you execute it on other nodes</para></listitem>

<listitem><para>You are responsible for ensuring that your scripts get
applied on all other nodes at the correct point during the replication
stream.  The best way of doing this with respect to adding and deleting
columns is to make sure that new columns always get added on the
replica nodes first and that columns being removed get dropped from the
master before they are dropped from the replicas.</para></listitem>

<listitem><para>DDL changes that rename a replicated table do not
inform &slony1; of the new table name.  If you change then name of
a replicated table you must allow &slony1; to find the new table name
by calling <xref linkend="function.updaterelname-p-only-on-node-integer-p-set-id-integer"/>
</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:
-->
