Commit scope rules v5

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 commit scope reference section..

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 parenthesed 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.

  • 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 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 CAMO.

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 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 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.