Commit scope rules
==================

Commit scope rules are at the core of the commit scope mechanism. They
define what the commit scope enforces.

Commit scope rules are composed of one or more operations that work in
combination. Use an AND between rules.

Each operation is made up of two or three parts: the commit scope group,
an optional confirmation level, and the kind of commit scope, which can
have its own parameters.

::

   commit_scope_group [ confirmation_level ] commit_scope_kind

A full formal syntax diagram is available in the `Commit scopes <https://www.enterprisedb.com/docs/pgd/latest/reference/tables-views-functions/commit-scopes/#commit-scope-syntax>`_ 
reference.

A typical commit scope rule, such as
``MAJORITY ORIGIN GROUP QUORUM COMMIT ABORT ON (timeout = 6s)`` , can be
broken down into its components. ``MAJORITY ORIGIN GROUP`` is the commit
scope group, specifying which nodes need to respond and confirm they
processed the transaction. In this example, a majority of nodes in the
origin node’s group must confirm.

No confirmation level is specified, which means that the default
(``visible`` ) is used. With ``visible`` , nodes confirm once all the
transaction’s changes are flushed to disk and are visible to other
transactions.

The last part of this operation is the commit scope kind, which in this
example is ``QUORUM COMMIT`` . ``QUORUM COMMIT`` is a synchronous
two-phase commit that coordinates across all participating nodes before
any node commits. The ``ABORT ON`` clause is mandatory and sets how long
to wait for quorum before aborting the transaction.

The commit scope group
----------------------

There are three kinds of commit scope groups: ``ANY`` , ``ALL`` , and
``MAJORITY`` . They’re all followed by a list of one or more groups in
parentheses. This list of groups combines to make a pool of nodes this
operation applies to. This list can be preceded by ``NOT`` , which
inverts the pool to be all other groups that aren’t in the list.

- ``ANY n`` is followed by an integer value, ``n`` . It translates to
  any ``n`` nodes in the listed groups’ nodes.

- ``ALL`` is followed by the groups and translates to all nodes in the
  listed groups’ nodes.

- ``MAJORITY`` is followed by the groups and translates to requiring a
  half, plus one, of the listed groups’ nodes to confirm, to give a
  majority.

- ``ANY n NOT`` is followed by an integer value, ``n`` . It translates
  to any ``n`` nodes that aren’t in the listed groups’ nodes.

- ``ALL NOT`` is followed by the groups and translates to all nodes that
  aren’t in the listed groups’ nodes.

- ``MAJORITY NOT`` is followed by the groups and translates to requiring
  a half, plus one, of the nodes that aren’t in the listed groups’ nodes
  to confirm, to give a majority.

All of the above expressions only consider data nodes in the groups in
their evaluation. Witness nodes and other non-data nodes are ignored.

The confirmation level
----------------------

PGD nodes can send confirmations for a transaction at different times.
In increasing levels of protection, from the perspective of the
confirming node, these are:

- ``received`` - A remote PGD node confirms the transaction immediately
  after receiving it, prior to starting the local application.

- ``replicated`` - Confirms after applying changes of the transaction
  but before flushing them to disk.

- ``durable`` - Confirms the transaction after all of its changes are
  flushed to disk.

- ``visible`` (default) - Confirms the transaction after all of its
  changes are flushed to disk and it’s visible to concurrent
  transactions.

In rules for commit scopes, you can append these confirmation levels to
the node group definition in parentheses with ``ON`` , as follows:

- ``ANY 2 (right_dc) ON replicated``

- ``ALL (left_dc) ON visible`` (default)

- ``ALL (left_dc) ON received AND ANY 1 (right_dc) ON durable``

..  Note::
   If you're familiar with PostgreSQL's `synchronous_standby_names`  feature, be aware that while the grammar for `synchronous_standby_names`  and commit scopes can look similar, there's a subtle difference. The former doesn't account for the origin node, but the latter does. For example, `synchronous_standby_names = 'ANY 1 (..)'`  is equivalent to a commit scope of `ANY 2 (...)` . This difference makes reasoning about majority easier and reflects that the origin node also contributes to the durability and visibility of the transaction.

The commit scope kinds
----------------------

Currently, there are four commit scope kinds. The following is a
summary, with links to more details.

SYNCHRONOUS COMMIT
^^^^^^^^^^^^^^^^^^

Synchronous Commit is a commit scope option that’s designed to behave
like the native Postgres ``synchronous_commit`` option, but is usable
from within the commit scope environment. It’s a synchronous
non-two-phase commit operation that supports an optional ``DEGRADE ON``
clause. The commit scope group that comes before this option controls
the groups and confirmation requirements the ``SYNCHRONOUS COMMIT``
uses.

For more details, see :ref:`Synchronous Commit <Synchronous Commit>`  .

QUORUM COMMIT
^^^^^^^^^^^^^

Quorum Commit is a synchronous two-phase commit that coordinates across
all participating nodes before any node commits. All participating nodes
commit together or roll back together. Before any node can commit
locally, Quorum Commit uses eager conflict resolution to prevent
inconsistencies rather than resolving them after the fact. Supported
commit scope groups are ``ALL`` , ``MAJORITY ORIGIN GROUP`` ,
``MAJORITY CLUSTER`` , and ``MAJORITY FOR EACH GROUP`` .

For more details, see :ref:`How Quorum Commit works <How Quorum Commit works>`  .

CAMO
^^^^

Commit At Most Once, or CAMO, allows the client/application, origin
node, and partner node to ensure that a transaction is committed to the
database at most once. Because the client is involved in the process, an
application will require modifications to participate in the CAMO
process.

For more details, see :ref:`Commit At Most Once <Commit At Most Once>`  .

LAG CONTROL
^^^^^^^^^^^

With Lag Control, when the system’s replication performance exceeds
specified limits, a commit delay can be automatically injected into
client interaction with the database, providing a back pressure on
clients. Lag Control has parameters to set the maximum commit delay that
can be exerted. It also has limits in terms of time to process or queue
size that trigger increases in that commit delay.

For more details, see :ref:`Lag Control <Lag Control>`  .

..  Note Legacy commit scope kind::
   `GROUP COMMIT`  is a legacy commit scope kind retained for backwards compatibility. For new deployments, use `QUORUM COMMIT`  instead. For more details, see  :ref:`Group Commit (legacy) <Group Commit (legacy)>`  .

.. ::
   ## Combining rules

Commit scope rules are composed of one or more operations that work in
combination. Use an AND to form a single rule. For example:

::

   MAJORITY (Region_A) SYNCHRONOUS COMMIT AND ANY 1 (Region_A) LAG CONTROL (MAX_LAG_SIZE = 50MB)

The first operation sets up a synchronous commit against a majority of
``Region_A`` . The second operation adds lag control that starts pushing
the commit delay up when any one of the nodes in ``Region_A`` has more
than 50MB of lag. This combination of operations allows the lag control
to operate when any node is lagging.
