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 9s, 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 that better utilizes the multi-master functionality. When
running without PGD Proxy, writes are distributed among the nodes and
replicated to one another, and conflict resolution is relied on for
maintaining consistency. This approach can be more efficient depending
on your architectural needs. However, PGD Proxy ensures lower contention
and conflict through the use of a write leader. For each proxy instance,
a single endpoint 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: 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 to add or subtract
from the cluster. It generally ensures 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 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 use its :ref:`built-in command-line interface <../cli>`  (CLI), which offers several useful
  commands. For example: - The `pgd nodes list <https://www.enterprisedb.com/docs/pgd/latest/cli/command_ref/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 nodes 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
-------------------------

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 approach 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 takes over its
responsibilities, minimizing downtime. Also, PGD includes self-healing
capabilities, where nodes that have failed or disconnected 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.
