Group Commit
============

The goal of Group Commit is to protect against data loss in case of
single node failures or temporary outages. You achieve this by requiring
more than one PGD node to successfully receive and confirm a transaction
at COMMIT time.

Requirements
------------

During normal operation, Group Commit is transparent to the application.
Transactions that were in progress during failover need the
reconciliation phase triggered or consolidated by either the application
or a proxy in between. This activity currently happens only when either
the origin node recovers or when it’s parted from the cluster. This
behavior is the same as with Postgres legacy built-in synchronous
replication.

Transactions committed with Group Commit use two-phase commit
underneath. Therefore, configure ``max_prepared_transactions`` high
enough to handle all such transactions originating per node.

Configuration
-------------

To use Group Commit, first define a :ref:`Commit scopes <Commit scopes>`  . The commit scope
determines the PGD nodes involved in the commit of a transaction.

Behavior
--------

The behavior of Group Commit depends on the configuration applied by the
commit scope.

Commit decisions
^^^^^^^^^^^^^^^^

You can configure Group Commit to decide commits in three different
ways: ``group`` , ``partner`` , and ``raft`` .

Group Commit decision is done through the consensus specified using the
same commit scope group settings used for the durability purposes. The
difference is that the commit decision is made based on PREPARE
replication while the durability checks COMMIT (PREPARED) replication.

The partner decision is what :ref:`Commit At Most Once <Commit At Most Once>`  uses. This approach works
only when there are two data nodes in the node group. These two nodes
are partners of each other, and the replica rather than origin decides
whether to commit something. This approach requires application changes
to use the CAMO transaction protocol to work correctly, as the
application is in some way part of the consensus. For more on this
approach, see :ref:`CAMO or commit-at-most-once <CAMO or commit-at-most-once>`  .

The raft option uses the built-in Raft consensus to decide whether
commit can happen. Currently, the global Raft is used. For this to work,
the majority of nodes across the whole cluster must work.

Conflict resolution
^^^^^^^^^^^^^^^^^^^

Conflict resolution can be ``async`` or ``eager`` .

Async means that PGD does optimistic conflict resolution during
replication using the row-level resolution as configured for given node.
This happens regardless of whether the origin transaction committed or
is still in progress. See :ref:`Conflicts <Conflicts>`  for details about how the
asynchronous conflict resolution works.

Eager means that conflicts are resolved eagerly (as part of agreement on
COMMIT), and conflicting transactions get aborted with a serialization
error. This approach provides greater isolation than the asynchronous
resolution at the price of performance. For the details about how Eager
conflict resolution works, see :ref:`Eager conflict resolution <Eager conflict resolution>`  .

Aborts
^^^^^^

To prevent a transaction that can’t get consensus on the COMMIT from
hanging forever, the ``ABORT ON`` clause allows specifying timeout.
After the timeout, the transaction abort is requested. If the
transaction is already decided to be committed at the time the abort
request is sent, the transaction does eventually COMMIT even though the
client might receive an abort message.

Limitations
-----------

Group Commit transactions can’t yet execute DDL, and they don’t support
explicit two-phase commit. Future releases might allow them. However,
the ``TRUNCATE`` command is allowed.

You can combine only CAMO transactions with the ``DEGRADE TO`` clause
for switching to asynchronous operation in case of lowered availability.

Eager and CAMO transactions aren’t currently supported in combination
with the decoding worker feature or with transaction streaming.
Installations using Eager must keep ``enable_wal_decoder`` and
``streaming_mode`` disabled for the PGD node group.

Synchronous replication uses a mechanism for transaction confirmation
different from Group Commit. The two aren’t compatible, and you must not
use them together. Therefore, whenever you Group Commit transactions,
make sure none of the PGD nodes are configured in
``synchronous_standby_names`` .

Currently, Raft commit decisions are extremely slow, producing very low
TPS. We recommended using them only with the ``eager`` conflict
resolution setting to get the Eager All-Node Replication behavior of PGD
4 and older.

Combining different commit decision options in the same transaction
isn’t supported. Combining different conflict resolution options in the
same transaction also isn’t supported.
