Architecture overview
=====================

EDB Postgres Distributed (PGD) is a distributed database solution that
extends PostgreSQL’s capabilities, enabling highly available and
fault-tolerant database deployments across multiple nodes. PGD provides
data distribution with advanced conflict management, data-loss
protection, high availability up to five 9’s, and throughput up to 5X
faster than native logical replication.

PGD is built on a multi-master foundation (Bi-directional replication,
or BDR) which is then optimized for performance and availability through
PGD Proxy. You can run PGD without PGD proxy if you need a custom
deployment better utilizing the multi-master functionality. When running
without PGD Proxy, writes are distributed amongst the nodes, replicated
to one another, and conflict resolution is relied upon for maintaining
consistency. This can be more efficient depending on your architectural
needs, however, PGD proxy ensures lower contention and conflict through
the use of a write leader, and for each proxy instance a single endpoint
automatically addresses all the data nodes in a group, removing the need
for clients to round robin multi-host connection strings. `Raft <<https://en.wikipedia.org/wiki/Raft_(algorithm>`_ 
>) is implemented to help the system make important decisions, like
deciding which node is the Raft election leader and which node is the
write leader.

High-level architecture
-----------------------

At the highest level, PGD comprises two main components: Bi-Directional
Replication (BDR) and PGD-proxy. BDR is a Postgres extension that
enables a multi-master replication mesh between different BDR-enabled
Postgres instances/nodes. :ref:`Routing functions <Routing functions>`  sends requests to the write
leader—ensuring a lower risk of conflicts (stronger consistency) between
nodes.

.. figure:: /images/always_on_1x3_updated.png
   :width: 70% 
   :alt: Diagram showing 3 application nodes, 3 proxy instances, and 3
   PGD nodes. Traffic is being directed from each of the proxy instances
   to the write leader node.

   Diagram showing 3 application nodes, 3 proxy instances, and 3 PGD
   nodes. Traffic is being directed from each of the proxy instances to
   the write leader node.

Changes are replicated directly, row-by-row between all nodes.
:ref:`Logical replication <Logical replication>`  in PGD is asynchronous by default, so only eventual
consistency is guaranteed (within seconds usually). However,
`commit scope <https://www.enterprisedb.com/docs../commit-scopes/commit-scopes>`_  options offer immediate consistency and durability
guarantees via :ref:`Commit At Most Once <Commit At Most Once>`  , :ref:`Group commit <Group commit>`  and :ref:`Synchronous Commit <Synchronous Commit>`  commits.

The Raft algorithm provides a mechanism for :ref:`Raft elections in depth <Raft elections in depth>`  leaders (both
Raft leader and write leader), deciding which nodes should be added or
subtracted from the cluster, and generally ensuring that the distributed
system remains consistent and fault-tolerant, even in the face of node
failures.

Architectural elements
----------------------

PGD comprises several key architectural elements that work together to
provide its distributed database solution:

- **PGD nodes**: These are individual Postgres instances that store and
  manage data. They are the basic building blocks of a PGD cluster.

- **Groups**: By default, all nodes are also members of a :ref:`Create the top-level group <Create the top-level group>` 
  with its own raft leader, but without a write-leader. PGD nodes can be
  further organized into :ref:`Groups and subgroups <Groups and subgroups>`  , which enhance manageability
  and high availability. Each group can contain multiple nodes, allowing
  for redundancy and failover within the group. Groups facilitate
  organized replication and data consistency among nodes within the same
  group and across different groups. Each group has its own write
  leader.

- **Replication mechanisms**: PGD’s replication mechanisms include
  Bi-Directional Replication (BDR) for efficient replication across
  nodes, enabling multi-master replication. BDR supports asynchronous
  replication by default, but can be configured for varying levels of
  synchronicity, such as :ref:`Group commit <Group commit>`  or :ref:`Synchronous Commit <Synchronous Commit>`  , to enhance
  data durability.

- **Monitoring tools**: To monitor performance, health, and usage with
  PGD, you can utilize its `built-in command-line interface <https://www.enterprisedb.com/docs../cli>`_  (CLI), which offers several
  useful commands. For instance, the :ref:`pgd nodes list <pgd nodes list>`  command provides a
  summary of all nodes in the cluster, including their state and status.
  The :ref:`pgd cluster show --health <pgd cluster show>`  command checks the health of the cluster, reporting
  on node accessibility, replication slot health, and other critical
  metrics. The `pgd events show <https://www.enterprisedb.com/docs/pgd/latest/cli/command_ref/events/show/>`_  command lists significant events like
  background worker errors and node membership changes, which helps in
  tracking the operational status and issues within the cluster.
  Furthermore, the BDR extension allows for monitoring your cluster
  using SQL using the :ref:`bdr.monitor_group_versions <bdr.monitor_group_versions>`  role.

Node types
^^^^^^^^^^

All nodes in PGD are effectively data nodes. They vary only in their
purpose in the cluster.

- \*\* :ref:`Data nodes <Data nodes>`  \*\*: Store and manage data, handle read and write
  operations, and participate in replication.

There are then three types of node which, although built like a data
node, have a specific purpose. These are:

- \*\* :ref:`Subscriber-only nodes <Subscriber-only nodes>`  \*\*: Subscribe to changes from data nodes for
  read-only purposes, used in reporting or analytics.

- \*\* :ref:`Witness nodes <Witness nodes>`  \*\*: Participate in the consensus process without
  storing data, aiding in achieving quorum and maintaining high
  availability.

- \*\* :ref:`Logical standby nodes <Logical standby nodes>`  \*\*: Act as standby nodes that can be promoted to
  data nodes if needed, ensuring high availability and disaster
  recovery.

Node roles
^^^^^^^^^^

Data nodes in a group can also take on particular roles to enable
particular features. These roles are transient and can be transferred to
any other capable node in the group if needed. These roles can include:

- **Raft leader**: Arbitrates and manages consensus between a group’s
  nodes.

- \*\* :ref:`Finding the write leader <Finding the write leader>`  \*\*: Receives all write operations from PGD
  Proxy.

Architectural Flexibility
-------------------------

Postgres Distributed (PGD) offers flexible options with how its
architecture can be deployed, maintained, and scaled to meet various
performance, availability, and compliance needs.

PGD supports rolling maintenance, including blue/green deployments for
both Postgres upgrades and other system or application-level changes.
This ensures that the database remains available during routine tasks
such as minor or major version upgrades, schema changes, and vacuuming
operations. The system seamlessly switches between active database
versions, achieving zero-downtime.

PGD provides automatic failover to ensure high availability. If a node
in the cluster becomes unavailable, another node automatically takes
over its responsibilities, minimizing downtime. Additionally, PGD
includes self-healing capabilities, where nodes that have failed or
disconnected can automatically reconnect to the cluster and resume
normal operations once the issue is resolved.

PGD allows for selective replication, enabling users to replicate only a
subset of data to specific nodes. This feature can be used to optimize
performance by reducing unnecessary data traffic between nodes or to
meet regulatory requirements, such as geographical data restrictions.
For instance, a healthcare application might only replicate patient data
within a specific region to comply with local data privacy laws.

With commit scopes, PGD also provides configurable durability.
Accordingly, durability can be increased from the default asynchronous
behavior and tuned using various configurable commit scopes:

- \*\* :ref:`Synchronous Commit <Synchronous Commit>`  \*\*: Works a lot like PostgreSQL’s
  synchronous_commit option in its underlying operation—requires writing
  to at least one other node at COMMIT time, but can be tuned to require
  all nodes.

- \*\* :ref:`Upgrading a CAMO-enabled cluster <Upgrading a CAMO-enabled cluster>`  \*\* (Commit at most once): Works by tracking each
  transaction with a unique ID and using a pair of nodes to confirm the
  transaction’s outcome, ensuring the application knows whether to retry
  the transaction or not.

- \*\* :ref:`Group commit <Group commit>`  \*\*: An experimental commit scope, the goal of
  which is to protect against data loss in case of single node failures
  of temporary outages by requiring more than one PGD node to
  successfully confirm a transaction at COMMIT time.

- \*\* :ref:`Lag Control <Lag Control>`  \*\*: If replication is running outside of set
  limits (taking too long for another node to be replicated to), a delay
  is injected into the node that originally received the transaction,
  slowing things down until other nodes have caught up.
