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

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

Commit scope rules are composed of one or more operations combined with
an ``AND`` .

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 may have it’s own parameters).

::

   commit_scope_group [ confimation_level ] commit_scope_kind

A full formal syntax diagram is available in the :ref:`commit scope reference section. <Commit scopes>`  .

If we look at a typical commit scope rule, we can now break it down into
its components:

::

   ANY 2 (group) GROUP COMMIT

The ``ANY 2 (group)`` is the commit scope group, specifying, for the
rule, of which nodes need to respond, confirming they have processed the
transaction. Specifically, here, any two nodes from the named group must
confirm.

There is no confirmation level here, but that only means that the
default is used. You can think of the rule in full as:

::

   ANY 2 (group) ON visible GROUP COMMIT

The visible setting means the nodes are able to confirm once the all the
transaction’s changes are flushed to disk and visible to other
transactions.

The last part of this operation is the commit scope kind, which here is
``GROUP COMMIT`` , a synchronous two-phase commit which will be
confirmed when any two nodes in the named group confirm they have
flushed and made visible the transactions changes.

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

There are three kinds of commit scope group, ``ANY`` , ``ALL`` and
``MAJORITY`` . They are all followed by a parenthesized list of one or
more groups, which combine to make a pool of nodes that this operation
will apply to. This list can be preceded by ``NOT`` which inverts to
pool to all other groups apart from those in the list. Witness nodes are
not eligible to be included in this pool as they do not replicate data.

-  ``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 are not in the listed groups nodes.

-  ``ALL NOT`` — is followed by the groups and translates to all nodes
   that are not in the listed group’s nodes.

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

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 are 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 is 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 kind
---------------------

There are, currently, four commit scope kinds. Each of them has their
own page, so we’ll be summarizing and linking to them here:

GROUP COMMIT
^^^^^^^^^^^^

Group commit is a synchronous two-phase commit which will be confirmed
according to the requirements of the commit scope group.
``GROUP COMMIT`` has a number of options which control whether
transactions should be tracked over interruptions (boolean, defaults to
off), how conflicts should be resolved (``async`` or ``eager`` ,
defaults to ``async`` ) and how a consensus is obtained (``group`` ,
``partner`` or ``raft`` , defaults to ``group`` ).

For further details see :ref:`Group commit <Group commit>`  .

CAMO
^^^^

Camo, Commit At Most Once, 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,
the application will require modifications to participate in the CAMO
process.

For further details see :ref:`CAMO or commit-at-most-once <CAMO or 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, and limits in terms of time to process or queue size
which will trigger increases in that commit delay.

For further details see :ref:`Lag Control <Lag Control>` 

SYNCHRONOUS_COMMIT
^^^^^^^^^^^^^^^^^^

Synchronous Commit is a commit scope option which is designed to be like
the legacy ``synchronous_commit`` option, but accessible within the
commit scope environment. Unlike ``GROUP COMMIT`` it is a synchronous
non-two-phase commit operation, with no parameters. The preceding commit
scope group controls what groups and confirmation requirements the
``SYNCHRONOUS_COMMIT`` will use.

For further details see :ref:`SYNCHRONOUS_COMMIT <SYNCHRONOUS_COMMIT>` 

Combining rules
---------------

A rule can have multiple operations, combined with 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 which will start
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.
