workload to be distributed
among them.
</para>
<para>
If queries are simply broadcast unmodified, functions like
<function>random()</function>, <function>CURRENT_TIMESTAMP</function>, and
sequences can have different values on different servers.
This is because each server operates independently, and because
SQL queries are broadcast rather than actual data changes. If
this is unacceptable, either the middleware or the application
must determine such values from a single source and then use those
values in write queries. Care must also be taken that all
transactions either commit or abort on all servers, perhaps
using two-phase commit (<xref linkend="sql-prepare-transaction"/>
and <xref linkend="sql-commit-prepared"/>).
<productname>Pgpool-II</productname> and <productname>Continuent Tungsten</productname>
are examples of this type of replication.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Asynchronous Multimaster Replication</term>
<listitem>
<para>
For servers that are not regularly connected or have slow
communication links, like laptops or
remote servers, keeping data consistent among servers is a
challenge. Using asynchronous multimaster replication, each
server works independently, and periodically communicates with
the other servers to identify conflicting transactions. The
conflicts can be resolved by users or conflict resolution rules.
Bucardo is an example of this type of replication.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Synchronous Multimaster Replication</term>
<listitem>
<para>
In synchronous multimaster replication, each server can accept
write requests, and modified data is transmitted from the
original server to every other server before each transaction
commits. Heavy write activity can cause excessive locking and
commit delays, leading to poor performance. Read requests can
be sent to any server. Some implementations use shared disk
to reduce the communication overhead. Synchronous multimaster
replication is best for mostly read workloads, though its big
advantage is that any server can accept write requests —
there is no need to partition workloads between primary and
standby servers, and because the data changes are sent from one
server to another, there is no problem with non-deterministic
functions like <function>random()</function>.
</para>
<para>
<productname>PostgreSQL</productname> does not offer this type of replication,
though <productname>PostgreSQL</productname> two-phase commit (<xref
linkend="sql-prepare-transaction"/> and <xref
linkend="sql-commit-prepared"/>)
can be used to implement this in application code or middleware.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<xref linkend="high-availability-matrix"/> summarizes
the capabilities of the various solutions listed above.
</para>
<table id="high-availability-matrix">
<title>High Availability, Load Balancing, and Replication Feature Matrix</title>
<tgroup cols="9">
<colspec colname="col1" colwidth="1.1*"/>
<colspec colname="col2" colwidth="1*"/>
<colspec colname="col3" colwidth="1*"/>
<colspec colname="col4" colwidth="1*"/>
<colspec colname="col5" colwidth="1*"/>
<colspec colname="col6" colwidth="1*"/>
<colspec colname="col7" colwidth="1*"/>
<colspec colname="col8" colwidth="1*"/>
<colspec colname="col9" colwidth="1*"/>
<thead>
<row>
<entry>Feature</entry>
<entry>Shared Disk</entry>
<entry>File System Repl.</entry>
<entry>Write-Ahead Log Shipping</entry>
<entry>Logical Repl.</entry>
<entry>Trigger-&zwsp;Based Repl.</entry>
<entry>SQL Repl. Middle-ware</entry>
<entry>Async. MM Repl.</entry>
<entry>Sync. MM Repl.</entry>