largest top-level transaction (measured by the amount of memory
currently used for decoded changes) is selected and streamed. However, in
some cases we still have to spill to disk even if streaming is enabled
because we exceed the memory threshold but still have not decoded the
complete tuple e.g., only decoded toast table insert but not the main table
insert.
</para>
<para>
Even when streaming large transactions, the changes are still applied in
commit order, preserving the same guarantees as the non-streaming mode.
</para>
</sect1>
<sect1 id="logicaldecoding-two-phase-commits">
<title>Two-phase Commit Support for Logical Decoding</title>
<para>
With the basic output plugin callbacks (eg., <function>begin_cb</function>,
<function>change_cb</function>, <function>commit_cb</function> and
<function>message_cb</function>) two-phase commit commands like
<command>PREPARE TRANSACTION</command>, <command>COMMIT PREPARED</command>
and <command>ROLLBACK PREPARED</command> are not decoded. While the
<command>PREPARE TRANSACTION</command> is ignored,
<command>COMMIT PREPARED</command> is decoded as a <command>COMMIT</command>
and <command>ROLLBACK PREPARED</command> is decoded as a
<command>ROLLBACK</command>.
</para>
<para>
To support the streaming of two-phase commands, an output plugin needs to
provide additional callbacks. There are multiple two-phase commit callbacks
that are required, (<function>begin_prepare_cb</function>,
<function>prepare_cb</function>, <function>commit_prepared_cb</function>,
<function>rollback_prepared_cb</function> and
<function>stream_prepare_cb</function>) and an optional callback
(<function>filter_prepare_cb</function>).
</para>
<para>
If the output plugin callbacks for decoding two-phase commit commands are
provided, then on <command>PREPARE TRANSACTION</command>, the changes of
that transaction are decoded, passed to the output plugin, and the
<function>prepare_cb</function> callback is invoked. This differs from the
basic decoding setup where changes are only passed to the output plugin
when a transaction is committed. The start of a prepared transaction is
indicated by the <function>begin_prepare_cb</function> callback.
</para>
<para>
When a prepared transaction is rolled back using the
<command>ROLLBACK PREPARED</command>, then the
<function>rollback_prepared_cb</function> callback is invoked and when the
prepared transaction is committed using <command>COMMIT PREPARED</command>,
then the <function>commit_prepared_cb</function> callback is invoked.
</para>
<para>
Optionally the output plugin can define filtering rules via
<function>filter_prepare_cb</function> to decode only specific transaction
in two phases. This can be achieved by pattern matching on the
<parameter>gid</parameter> or via lookups using the
<parameter>xid</parameter>.
</para>
<para>
The users that want to decode prepared transactions need to be careful about
below mentioned points:
<itemizedlist>
<listitem>
<para>
If the prepared transaction has locked [user] catalog tables exclusively
then decoding prepare can block till the main transaction is committed.
</para>
</listitem>
<listitem>
<para>
The logical replication solution that builds distributed two phase commit
using this feature can deadlock if the prepared transaction has locked
[user] catalog tables exclusively. To avoid this users must refrain from
having locks on catalog tables (e.g. explicit <command>LOCK</command> command)
in such transactions.
See <xref linkend="logicaldecoding-synchronous-caveats"/> for the details.
</para>
</listitem>
</itemizedlist>
</para>
</sect1>
</chapter>